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