Is the following well defined and allowed?
Steven Schveighoffer
schveiguy at yahoo.com
Fri Mar 2 14:39:32 UTC 2018
On 3/1/18 5:27 PM, ag0aep6g wrote:
> You're looking at the behavior of the compiled executable. Then it makes
> sense to say that a program compiled with the checks has defined
> behavior (throwing Errors) and a program without the checks does
> something undefined (because the compiler manual doesn't say that
> anything in particular is supposed to happen).
No, I'm looking at the source code.
At the very basic level, you have this:
assert(foo == 0);
Or whatever other condition you have. What this does is gives the
compiler leeway to ASSUME foo is 0 at this point. It can make any number
of optimizations assuming this. If foo is NOT equal to 0 at this point,
then it is a program error, and the assumptions may cause bad things to
happen.
When you compile in normal mode, this assert causes an Error to be
thrown, before your code can do any damage.
When you compile without asserts, this causes undefined behavior.
The various switches and modes can say whether asserts or other checks
are present or not, and if they are not, the compiler is going to
execute your UB code with those wrong assumptions. But ONLY if the
assert would have been false.
I extend this same treatment and logic to all checks: contracts, bounds
checks, overlapping slice assign checks, etc. To me, they aren't any
different than asserts. They aren't any different if they are in @safe
code or @system code.
> That's not how I understand/use "undefined behavior". To me, it's the D
> source code that can have "undefined behavior". When it does, the
> program (as given in source code) is invalid and the compiler can do
> whatever it wants with it. It may:
>
> 1) reject the program statically, or it may
> 2) generate code that throws an Error at run time, or it may
> 3) generate code that does something arbitrary.
>
> With that meaning of UB, out-of-bounds accesses and overlapping copies
> have undefined behavior in @system code, but they have defined behavior
> in @safe code.
By default, both @system and @safe code have bounds checks. So by
default, it is defined behavior (an Error is thrown) regardless of the
safety.
If you turn the checks off (through any means) then it becomes UB.
> In this interpetation, -noboundscheck switches DMD to a different
> dialect of D. In that dialect, out-of-bounds accesses (and overlapping
> copies, apparently) always have UB, in both @system and @safe code. That
> defeats the purpose of @safe. Which is why I don't really care for that
> dialect.
I agree, I think we should remove the option to disable bounds checks on
@safe code, in any way. It's too dangerous. If you want performance that
comes without bounds checks, use a trusted escape, or write system code.
-Steve
More information about the Digitalmars-d
mailing list