January 20, 2021
On 1/19/21 11:21 PM, Ola Fosheim Grostad wrote:
> On Wednesday, 20 January 2021 at 04:15:24 UTC, Steven Schveighoffer wrote:
>> Only if the real item is actually const. This is literally the first example on cppreference:
>>
>>     int i = 3;                 // i is not declared const
>>     const int& rci = i;
>>     const_cast<int&>(rci) = 4; // OK: modifies i
>>
> 
> How is this different from D? How does this lead to different code gen?
> 

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);

-Steve
January 20, 2021
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?

How about this?

union t {int x; const int y;};


January 20, 2021
On Wednesday, 20 January 2021 at 05:12:15 UTC, Ola Fosheim Grostad wrote:
> Wasnt D supposed to eliminate UB?
>
> How about this?
>
> union t {int x; const int y;};

Or worse:
import std.stdio;
union t {int x; immutable int y;};
void main()
{

    t a;
    a.x=3;
    writeln(a.y);
    a.x=4;
    writeln(a.y);
}
January 20, 2021
>
> How is this different from D? How does this lead to different code gen?

Consider a function with a `const int[]` argument. In D, when generating code for the caller, it is allowed to assume that the callee won't change the contents of the array, unless it is in global space or passed via another argument.

The difference to C++ is that the above applies even if the array contains mutable values from the caller perspective:

```
long sum (const int[] arg);
void foo
{  auto arr = [1,2,3];
   auto sum = arr.sum; //codegen can assume that `arr` won't change
}
```
January 20, 2021
On Wednesday, 20 January 2021 at 09:25:51 UTC, Dukc wrote:
> long sum (const int[] arg);
> void foo
> {  auto arr = [1,2,3];
>    auto sum = arr.sum; //codegen can assume that `arr` won't change
> }

The called function has to be @pure, as the slice could reference a global...


January 20, 2021
On Wednesday, 20 January 2021 at 09:53:34 UTC, Ola Fosheim Grostad wrote:
> On Wednesday, 20 January 2021 at 09:25:51 UTC, Dukc wrote:
>> long sum (const int[] arg);
>> void foo
>> {  auto arr = [1,2,3];
>>    auto sum = arr.sum; //codegen can assume that `arr` won't change
>> }
>
> The called function has to be @pure, as the slice could reference a global...

Not in this case, as the caller knows `arr` is a only referenced locally. Had `foo` received `arr` as argument, then `sum` would have to be `pure` for the optimization.
January 20, 2021
On Wednesday, 20 January 2021 at 10:00:01 UTC, Dukc wrote:
> On Wednesday, 20 January 2021 at 09:53:34 UTC, Ola Fosheim Grostad wrote:
> Not in this case, as the caller knows `arr` is a only referenced locally. Had `foo` received `arr` as argument, then `sum` would have to be `pure` for the optimization.

Yes, sure. I was thinking in terms of optimizing utility functions. You still also have to deal with aliasing when you have multiple in params.
January 20, 2021
On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei Alexandrescu wrote:
> On 1/19/21 4:50 PM, Q. Schroll wrote:
>> In C++, the noexcept specifier means you cannot throw anything.
>> In D,   the nothrow  specifier means you cannot throw Exceptions, but anything else.
>
> Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...

nothrow is still a terrible name for something that can still throw.

January 20, 2021
On Wednesday, 20 January 2021 at 05:48:28 UTC, Ola Fosheim Grostad wrote:
> Or worse:
> import std.stdio;
> union t {int x; immutable int y;};
> void main()
> {
>
>     t a;
>     a.x=3;
>     writeln(a.y);
>     a.x=4;
>     writeln(a.y);
> }

This seems like a bug to me. Especially since the compiler even allows this:

t b = { y: 4 };
a = b;

Changing "union" to "struct" produces the expected error message:

Error: cannot modify struct instance `a` of type `t` because it contains `const` or `immutable` members
January 20, 2021
On Wednesday, 20 January 2021 at 12:37:41 UTC, Paul Backus wrote:
> This seems like a bug to me. Especially since the compiler even

Using a pointer to the immutable would indeed be unsound...

Best fix is tagged union.