January 20, 2021
On 1/20/21 12:12 AM, Ola Fosheim Grostad wrote:
> On Wednesday, 20 January 2021 at 05:04:44 UTC, Steven Schveighoffer wrote:
>> On 1/19/21 11:21 PM, Ola Fosheim Grostad wrote:
>> This is undefined behavior in D. How does it lead to different code Gen? This code could pass in D, but the equivalent C++ would have to fail since it's not UB:
>>
>> int i = 3;
>> const int *j = &i;
>> *(cast(int *)j) = 4;
>> assert(i == 3);
> 
> Wasnt D supposed to eliminate UB?

No.

> 
> How about this?
> 
> union t {int x; const int y;};
> 
> 

What's wrong with that? const is allowed to refer to mutable data.

But it's not usable in @safe code (which IS supposed to eliminate UB).

But technically, you can set one union member and as long as you don't use the other, it's never UB. In this case, however, it would seem fine.

Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set.

And again, disallowed in @safe code.

-Steve
January 20, 2021
On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
> But technically, you can set one union member and as long as you don't use the other, it's never UB. In this case, however, it would seem fine.
>
> Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set.

Where does the spec say that unions cannot be used for type punning?


January 20, 2021
On 1/20/21 9:48 AM, Ola Fosheim Grostad wrote:
> On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
>> But technically, you can set one union member and as long as you don't use the other, it's never UB. In this case, however, it would seem fine.
>>
>> Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set.
> 
> Where does the spec say that unions cannot be used for type punning?
> 
> 

I should say, it's undefined behavior if you ever use the immutable value and then mutate the value (just like if you cast it).

-Steve
January 20, 2021
On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
> Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set.
>
> And again, disallowed in @safe code.

This version compiles even with @safe:

import std.stdio;
union t {int x; immutable int y;};
void main() @safe
{

    t a = { x: 0 };
    writeln(a.y);
    t b = { y: 4 };
    a = b; // oops
    writeln(a.y);
}
January 20, 2021
On 1/20/21 10:13 AM, Paul Backus wrote:
> On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
>> Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set.
>>
>> And again, disallowed in @safe code.
> 
> This version compiles even with @safe:
> 
> import std.stdio;
> union t {int x; immutable int y;};
> void main() @safe
> {
> 
>      t a = { x: 0 };
>      writeln(a.y);
>      t b = { y: 4 };
>      a = b; // oops
>      writeln(a.y);
> }

That seems like a bug. Writing the x directly fails in @safe code.

-Steve
January 20, 2021
On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer wrote:
> On 1/20/21 10:13 AM, Paul Backus wrote:
>> 
>> This version compiles even with @safe:
>> 
>> import std.stdio;
>> union t {int x; immutable int y;};
>> void main() @safe
>> {
>> 
>>      t a = { x: 0 };
>>      writeln(a.y);
>>      t b = { y: 4 };
>>      a = b; // oops
>>      writeln(a.y);
>> }
>
> That seems like a bug. Writing the x directly fails in @safe code.
>
> -Steve

I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line

    writeln(a.y);

...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].

[1] https://dlang.org/spec/function.html#safe-aliasing
January 20, 2021
On 1/20/21 10:31 AM, Paul Backus wrote:
> On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer wrote:
>> On 1/20/21 10:13 AM, Paul Backus wrote:
>>>
>>> This version compiles even with @safe:
>>>
>>> import std.stdio;
>>> union t {int x; immutable int y;};
>>> void main() @safe
>>> {
>>>
>>>      t a = { x: 0 };
>>>      writeln(a.y);
>>>      t b = { y: 4 };
>>>      a = b; // oops
>>>      writeln(a.y);
>>> }
>>
>> That seems like a bug. Writing the x directly fails in @safe code.
>>
> 
> I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line
> 
>      writeln(a.y);
> 
> ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
> 

Thanks for that link, I wasn't aware of that list.

In my Dconf online presentation, I found numerous bugs surrounding unions and @safe code.

For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!)

-Steve
January 20, 2021
On Wednesday, 20 January 2021 at 16:07:26 UTC, Steven Schveighoffer wrote:
> On 1/20/21 10:31 AM, Paul Backus wrote:
>> On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer wrote:
>>> On 1/20/21 10:13 AM, Paul Backus wrote:
>>>> [...]
>>>
>>> That seems like a bug. Writing the x directly fails in @safe code.
>>>
>> 
>> I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line
>> 
>>      writeln(a.y);
>> 
>> ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
>> 
>
> Thanks for that link, I wasn't aware of that list.
>
> In my Dconf online presentation, I found numerous bugs surrounding unions and @safe code.
>
> For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!)
>
> -Steve

Are those bugs reported?
January 20, 2021
On Wednesday, 20 January 2021 at 15:31:30 UTC, Paul Backus wrote:
>
> I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line
>
>     writeln(a.y);
>
> ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
>
> [1] https://dlang.org/spec/function.html#safe-aliasing

https://issues.dlang.org/show_bug.cgi?id=21561
January 20, 2021
On 1/20/21 12:08 PM, Imperatorn wrote:
> On Wednesday, 20 January 2021 at 16:07:26 UTC, Steven Schveighoffer wrote:
>> On 1/20/21 10:31 AM, Paul Backus wrote:
>>> On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer wrote:
>>>> On 1/20/21 10:13 AM, Paul Backus wrote:
>>>>> [...]
>>>>
>>>> That seems like a bug. Writing the x directly fails in @safe code.
>>>>
>>>
>>> I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line
>>>
>>>      writeln(a.y);
>>>
>>> ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
>>>
>>
>> Thanks for that link, I wasn't aware of that list.
>>
>> In my Dconf online presentation, I found numerous bugs surrounding unions and @safe code.
>>
>> For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!)
>>
> 
> Are those bugs reported?

I don't know if I reported mine. I assumed at the time that it was just the expected behavior, but the spec seems to suggest otherwise.

I'll report it. Looks like Paul did his.

-Steve