Getting action on your favorite D issues

ag0aep6g anonymous at example.com
Sun Jun 7 14:55:07 UTC 2020


On Sunday, 7 June 2020 at 13:10:22 UTC, Avrina wrote:
> On Saturday, 6 June 2020 at 20:20:54 UTC, ag0aep6g wrote:
[...]
>> ----
>> int f() { int x = void; x = 42; return x + 1; } /* This is 
>> fine. */
>> int g() { int x = void; return x + 1; } /* This is not. */
>> ----
>>
>> If LDC defines behavior for `g`, it creates a dialect of D 
>> which has less undefined behavior than (current) standard D.
>
> g is defined behavior, or it wouldn't work. The result may not 
> be known, but it is defined. Otherwise, what, a compiler could 
> just insert anything they want there. An assert(0) that 
> terminates the application.

Per the current spec, g has undefined behavior. Yes, a compiler 
can just insert anything it wants there. Yes, it can replace the 
body of g with `assert(0);`. That's how undefined behavior works.

Please consider the possibility that you might not fully 
understand what "undefined behavior" means.

> The issue isn't with void initializers. It is whether a bool 
> should be treated as a byte or single bit. Void initialization 
> just leads to the problem, there's many ways it can be 
> expressed. Someone else has shown it with unions. You can also 
> just use casts as well and you'll get the same problem.
>
>     bool e() { int x = 2; return *cast(bool*)&x; }

It's true that you can get exotic bools in other ways that also 
pass as @safe. That's a valid counter to Patrick Schluter's 
remark about undefined behavior.

If we look at an example that has undefined behavior (per the 
spec), then Patrick is right that we can't expect any particular 
result. With undefined behavior, a bool can be true and false at 
the same time.

But if we look at an example that doesn't have undefined 
behavior, then a bool should really be either true or false and 
not both. If it's both, the compiler has a bug. This is what 
you're saying, and I agree.

On top of that, an example that passes as @safe cannot have 
undefined behavior (per the spec). If the compiler accepts code 
with undefined behavior as @safe, there is another bug (in the 
compiler or in the spec). This is what Walter's pull request is 
about.

> The issue with void initializers is that they aren't actually 
> @safe, just as I can't use cast's in @safe code, I shouldn't be 
> allowed to use void initializers in @safe.

I think that's a reasonable stance. And it's what the spec says 
at the moment. But it's not the only way to resolve the issue. 
And judging from his pull request, it's not how Walter wants to 
proceed.

On a side note: You can use casts in @safe code. Not all of them, 
of course, but your reinterpret cast above actually compiles as 
@safe when you compile with -preview=dip1000.

[...]
>> True. Which is why a lot of fixing needs to be done. Sometimes 
>> the spec needs to be changed, sometimes the implementation, 
>> sometimes both.
>
> No one is going to waste their time with that.

That's just not true. It doesn't happen as fast as everyone would 
like, but bugs are getting fixed.

[...]
>> Sure. But as long as the PR is in limbo, Patrick Schluter has 
>> a point when he says that "undefined behaviour is undefined 
>> behaviour".
>
> It's not though. There is expected behavior for void 
> initializers. Otherwise what you are saying is that C++ has 
> undefined behavior for using variables that aren't initialized 
> (which are all of them unless they are initialized first). But 
> it doesn't. The behavior is expected. The root of the problem 
> isn't with void initialization because the behavior is defined. 
> The problem is with the boolean type and the loose definition 
> the spec provides it. Boolean is undefined behavior in D, as 
> long as the implementation in DMD and LDC differ, and there's 
> nothing in the spec to define it.

The spec clearly says that using an uninitialized value has 
undefined behavior. That doesn't go away just because you don't 
like it, or because C++ doesn't have that rule.

But yes, the issue with exotic bools goes beyond undefined 
behavior, as the examples with unions and casts show. As far as I 
can tell, the spec doesn't rule those out as undefined behavior.



More information about the Digitalmars-d mailing list