[Issue 18016] using uninitialized value is considered @safe but has undefined behavior

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Jun 11 10:31:36 UTC 2019


https://issues.dlang.org/show_bug.cgi?id=18016

--- Comment #17 from ag0aep6g <ag0aep6g at gmail.com> ---
(In reply to Manu from comment #14)
> > As a whole, using an uninitialized variable wouldn't be implementation defined. > That would be silly.
> 
> I don't think it's silly at all. It's perfectly fine.
> Please don't butcher LDC to accommodate DMD's quirks.
> Reading from uninitialised memory is an invalid operation, and unnecessarily
> initialising memory has real cost.

If we made it implementation defined, the operation would become valid. You
would expressly be allowed to write `void main() { int x = void; return x; }`.
The spec would say: "I am 100% sure that that's a valid program, and I have no
opinion whatsoever on what it should do." I think that'd be silly.

As it is, the operation is invalid, because its behavior is undefined. That's
not silly. As far as I can tell, you're arguing for this, not for
implementation defined behavior.


(In reply to Steven Schveighoffer from comment #15)
> How would it omit the return statement?
> 
> The code above seems to compile with ldc and writeln(f()) seems to print
> something (0 in fact on my test). Where is the omission? Not saying your
> assertion is false, I just don't understand how it can omit everything that
> depends on an access of uninitialized data.

I think I was wrong there. I had tested something like this:

----
int main(string[] args)
{
    int x = void;
    int y = cast(int) args.length;
    return x + y;
}
----

`ldc2 -O test.d` generates this:

----
0000000000000000 <_Dmain>:
   0:   c3                      ret
----

Here, everything's gone, including args.length. The result isn't "return
args.length plus garbage", it's just "return garbage". That looked to me like
LDC omits code that depends on the value of x.

But it can be interpreted differently: The value of `x` is arbitrary. LDC can
choose it so that whatever `ret` returns is the same as returning x +
args.length. Then omitting the args.length line is just normal optimization.

So I don't have an example where LDC's current behavior is incompatible with
Walter's PR.

In fact, when I try to restrict the values that `x` can possibly have, e.g. by
returning `x & 1`, LDC catches that and emits code that matches. Maybe LDC
already adheres to the "implementation defined value" rule.

--


More information about the Digitalmars-d-bugs mailing list