Assert and undefined behavior
kdevel
kdevel at vogtner.de
Fri Oct 13 11:26:54 UTC 2017
On Friday, 13 October 2017 at 02:22:24 UTC, Jonathan M Davis
wrote:
> You've told it that i should never be 3 at that point and that
> it's a bug if it is, and as such, it is free to assume that i
> is never 3 after the assertion even if the assertion is
> compiled out with -release - that is the only place that
> undefined behavior may enter into it.
Thanks for the clarification! This is a difference to C where
assert has only a diagnostic purpose. Disabling assertions in C
(by setting NDEBUG) does AFAICS neither introduce undefined
behavior nor is the compiler entitled to optimize code away based
on the assertion. This C program
--- test.c
#include <stdio.h>
#define NDEBUG 1
#include <assert.h>
int main ()
{
int i = 3;
assert (i != 3);
if (i == 3)
printf ("%d\n", i);
return 0;
}
---
is IMHO conforming and it is defined to print 3 in a conforming
environment. The 'corresponding' D program
--- assert4.d
import std.stdio;
int main ()
{
int i = 3;
assert (i != 3);
if (i == 3)
writef ("%d\n", i);
return 0;
}
---
is 'conforming' (but buggy) under non-release-D and
'non-conforming' (because of the undefined behavior) otherwise.
Is this judgement correct?
> If the compiler does an optimization based on the fact that i
> isn't 3, and it is, and -release is used, then you could get
> some weird behavior when the code reaches the lines after the
> assertion - but by definition, you already have a bug if i is
> 3, and your program in general is assuming that i isn't 3 at
> that point, so you're going to get bad behavior either way.
I would like to make a clear distiction between "bug" or "bad
behavior" on the one hand and "undefined behavior" on the other.
"Bug" and "bad behavior" address the outcome of a computation
while "undefined behavior" is an (abstract, formal) property of a
piece of code with respect to a certain language specification.
> The fact that your assertion failed means that you have a logic
> error in your program, and it is therefore in an invalid state
> and will likely not behave correctly.
Under non-release-D the program is perfectly valid and behaves
exactly as expected. In relase-D it makes no sense to discuss if
the state of program is valid or if the program behaves
correctly, since it is non-conforming because of the undefined
behavior.
(...)
> On a side note, I would point out that talking about "debug
> mode" with D gets annoyingly ambiguous, because that kind of
> implies the -debug flag, which has nothing to do with
> assertions and which actually can be used in conjunction with
> -release (all -debug does is enable debug{} blocks), which is
> why I try to avoid the term debug mode - though I assume that
> you meant when -release isn't used, since that's often what
> folks mean.
Agreed.
More information about the Digitalmars-d-learn
mailing list