Assert and undefined behavior

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Oct 12 20:27:03 UTC 2017


On Thursday, October 12, 2017 20:15:41 kdevel via Digitalmars-d-learn wrote:
> On Thursday, 12 October 2017 at 15:37:23 UTC, John Burton wrote:
> > C++ compilers can and do perform such optimizations so I was
> > wondering if assert in D could cause such behavior according to
> > the spec.
>
> In the context of ISO-C++ it is meaningless to reason about the
> "actual behavior" of a non-conforming program ("start WW III"
> etc.). You may find details here:
> <http://en.cppreference.com/w/cpp/language/ub>
>
> As standard oriented C++ (or C or FORTRAN) programmers we avoid
> undefined behavior not because we would want to prevent WW III,
> but because we want to write and reason about conforming code
> only.
>
> IIRC C++'s assert is defined in the ISO-C standard. There we can
> read:
>
> "The assert macro puts diagnostic tests into programs; it expands
> to a void expression. When it is executed, if expression (which
> shall have a scalar type) is false (that is, compares equal to
> 0), the assert macro writes information about the particular call
> that failed [...] on the standard error stream in an
> implementation-defined format). It then calls the abort function."
>
> So in C/C++
>
> ---
> int main ()
> {
>     assert (0);
>     return 0;
> }
> ---
>
> is a perfectly valid (conforming) program.
>
> D ist not standardized (yet) hence there is no such thing as a
> "standard conforming D implementation" or a "standard conforming
> D program". The D documentation is simply the manual of a set of
> programs (compiler, tools) which may or may not be correctly be
> described therin. According to
> <https://dlang.org/spec/contracts.html> the program
>
> ---
> void main ()
> {
>     assert (false);
> }
> ---
>
> qualifies as "invalid, and therefore has undefined behaviour." A
> statement, which makes no sense to me. Either it is a "debugging
> aid", that implies defined behavior, or it is undefined behavior,
> then assert (false) cannot aid debugging.

assert(false) is a bit special in that it's never removed (it becomes a HLT
instruction with -release), and the compiler recognizes that you're saying
that that code is supposed to be unreachable (e.g. it then doesn't require a
return statement after assert(0) if if the function is supposed to return).
Obviously, asserting false in main is pointless, and you're dead wrong about
the code being unreachable, but the fact that you're wrong is caught when
the line is reached, and the program is killed. And that behavior is
completely defined, because it's known at compile time that the condition
being tested by the assertion is false.

assert(false) does aid in debugging in that you're indicating that a piece
of code is supposed to be unreachable, and if you reach it, then you have a
bug, and you catch it, but really, it's a special case indicating that a
piece of code is supposed to be unreachable rather than an assertion to test
that a particular condition is true at a particular point in the program,
which is what assertions normally do.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list