Can we just have struct inheritence already?

Exil Exil at gmall.com
Fri Jun 14 00:41:25 UTC 2019


On Thursday, 13 June 2019 at 21:18:16 UTC, Timon Gehr wrote:
> On 13.06.19 22:55, Exil wrote:
>> On Thursday, 13 June 2019 at 19:21:53 UTC, Tim wrote:
>>> On Tuesday, 11 June 2019 at 00:30:27 UTC, Walter Bright wrote:
>>>> If you want @safe to mean "no undefined behavior", that is a 
>>>> valid opinion, but that is not what @safe in D is currently 
>>>> defined as. It is currently defined as "memory safe". If you 
>>>> can find a case where an int with garbage in it can cause 
>>>> memory corruption in @safe code, that would indeed be a bug 
>>>> in D.
>>>
>>> The following code causes memory corruption, because a bool 
>>> has garbage in it.
>>>
>>> import std.stdio;
>>>
>>> // Returns newly allocated data with increased value if b is 
>>> true.
>>> // Returns same data otherwise.
>>> const(int)* test(immutable int *data, bool b) @trusted
>>> {
>>>     int *data2;
>>>     if(!b)
>>>     {
>>>         writeln("b seems to be false");
>>>         // The cast can be trusted, because data2 will only 
>>> be modified if b is true.
>>>         data2 = cast(int*)data;
>>>     }
>>>     else
>>>     {
>>>         writeln("b seems to be true");
>>>         data2 = new int(*data);
>>>     }
>>>
>>>     if(b)
>>>     {
>>>         writeln("b seems to be true");
>>>         *data2 += 1;
>>>     }
>>>     return data2;
>>> }
>>>
>>> void main() @safe
>>> {
>>>     bool b = void;
>>>     immutable int *data = new immutable int(1);
>>>     writeln("data before: ", *data);
>>>     const int *data2 = test(data, b);
>>>     writeln("data after: ", *data);
>>>     writeln("data2 after: ", *data2);
>>> }
>>>
>>> After compiling it with dmd and running it I get the 
>>> following output:
>>> data before: 1
>>> b seems to be false
>>> b seems to be true
>>> data after: 2
>>> data2 after: 2
>>>
>>> The immutable integer pointed to by data is modified. The 
>>> function test is @trusted, but only modifies the immutable 
>>> data, because b seems to be true and false at the same time.
>>> Normally a bool is internally 0 or 1 and the compiler can 
>>> assume that. If b has another value and !b is implemented as 
>>> ~b, then b and !b can both be true.
>>>
>>> This means, that uninitialized data can result in memory 
>>> corruption.
>> 
>> This problem happens because you are used @trusted. If you 
>> used @safe you wouldn't be able to increment pointers and 
>> modify the values the way you did in @trusted.
>
> What that code illustrates is that `void` initialization leads 
> to boolean values that are both `true` and `false` at the same 
> time.
> The @trusted function in the example can't do anything bad 
> assuming that `b` is either true or false. If `void` 
> initialization is @safe, @trusted functions can no longer 
> assume that boolean parameters cannot be `true` and `false` at 
> the same time. What's more, neither can @safe functions.
>
> In my book, an optimizer that can't elide the `if(b)` in the 
> above code is a bad optimizer. Therefore either `void` 
> initialization should not be @safe, or `void` initialization of 
> a bool should be guaranteed to result in a value that is either 
> true or false, but not both.

They aren't both true and false at the same time. Merely the code 
that is generated seems to be most likely checking that it is 1. 
This is more a bug with the compiler, nothing more. It should 
only be checking if the value is zero, anything else should be 
true. Seems to change quite a lot looking at the output. But then 
that's DMD's backend for you, wouldn't hurt to add a test for 
this.






More information about the Digitalmars-d mailing list