If you compile and run the following code, what happens?

void main()
{
   assert(0, "error message");
}

answer: it depends. On OSX, if you compile this like so:

dmd testassert.d
./testassert

You get this message + stack trace:

[email protected](3): error message

Not bad. But assert(0) is special in that it is always enabled, even in release mode. So let's try that:

dmd -release testassert.d
./testassert
Segmentation fault: 11

WAT. The explanation is, assert(0) is translated in release mode to a HLT instruction. on X86, this results in a segfault. But a seg fault is tremendously less useful. Let's say you are running a 10k line program, and you see this. Compared with seeing the assert message and stack trace, this is going to cause hours of extra debugging.

Why do we do this? I'm really not sure. Note that "error message" is essentially not used if we have a seg fault. Throwing an assert error shouldn't cause any issues with stack unwinding performance, since this can be done inside a nothrow function. And when you throw an AssertError, it shouldn't be caught anyway.

Why can't assert(0) throw an assert error in release mode instead of segfaulting? What would it cost to do this instead?

-Steve

Reply via email to