20

As per this article:

If you try and lock a non-recursive mutex twice from the same thread without unlocking in between, you get undefined behavior.

My very naive mind tells me why don't they just return an error? Is there a reason why this has to be UB?

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • You may be wanting to use atomic_flag with the default memory order. It doesn't have data races and never throws exceptions like mutex does with multiple unlock calls (and aborts uncontrollably, I might add...). Alternatively, there is atomic (e.g. atomic[bool] or atomic[int] (with triangle brackets, not [])), which has nice functions like load and compare_exchange_strong. http://www.cplusplus.com/reference/atomic/atomic_flag/ http://www.cplusplus.com/reference/atomic/atomic/ – Andrew Feb 19 '17 at 23:40
  • Also as the `mutex` might be implemented with the OS native mutex, then it make sense to not define what could be different on different OS so that `std::mutex` could be a thin wrapper around OS provided mutex. – Phil1970 May 25 '17 at 23:29

2 Answers2

34

Because it never happens in a correct program, and making a check for something that never happens is wasteful (and to make that check it needs to store the owning thread ID, which is also wasteful).

Note that it being undefined allows debug implementations to throw an exception, for example, while still allowing release implementations to be as efficient as possible.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 1
    good A, but tbh I think good dbg implementations should assert, since ppl sometimes :P write code that eats exceptions without making much noise. :D – NoSenseEtAl Jan 24 '13 at 11:45
16

Undefined behavior allows implementations to do whatever is fastest/most convenient. For example, an efficient implementation of a non-recursive mutex might be a single bit where the lock operation is implemented with an atomic compare-and-swap instruction in a loop. If the thread that owns the mutex tries to lock it again it will deadlock because it is waiting for the mutex to unlock but since nobody else can unlock it (unless there's some other bug where some thread that doesn't own it unlocks it) the thread will wait forever.

Geoff Reedy
  • 34,891
  • 3
  • 56
  • 79