Re: Cast converts AA to rvalue?

2022-08-10 Thread ag0aep6g via Digitalmars-d-learn

On Wednesday, 10 August 2022 at 17:14:08 UTC, Johan wrote:

```
void f() {
aa[1] = 1; // error
}
shared static this()
{
f();
}
```

I had considered it, but discarded it... `f` is also a template 
in our code. Your remark made me check again, and the call 
chain is short, perhaps I'll convert `f` to a template mixin... 
Unfortunately doesn't work: "immutable variable `aa` 
initialization is not allowed in nested function `f`".


If you can build a mutable version of the array in a `pure` 
function, you can do it like this:


```d
int[int] make_aa() pure
{
int[int] maa;
maa[1] = 1; /* or function calls, or whatever */
return maa;
}
immutable int[int] aa;
shared static this()
{
aa = make_aa();
}
```

If you can't do it in a `pure` function, you can do it with a 
cast: `aa = cast(immutable) make_aa();`.


Casting from mutable to immutable is better, because it does not 
have undefined behavior (as long as you don't use a mutable 
reference later). Your casting away immutable and then mutating 
does have undefined behavior.


Re: Cast converts AA to rvalue?

2022-08-10 Thread Johan via Digitalmars-d-learn

On Wednesday, 10 August 2022 at 09:52:10 UTC, ag0aep6g wrote:

On 10.08.22 10:20, Johan wrote:

```
shared immutable int[int] aa;
void main () {
     // (cast()aa)[1] = 1; // works without immutable
     (*cast(int[int]*)())[1] = 1;
}
```


We have shared static constructors for that:

shared static this()
{
aa[1] = 1; /* no cast needed */
}


But our code is not a toy example ;-)  (sorry for unnecessary 
snarky remark)


```
void f() {
aa[1] = 1; // error
}
shared static this()
{
f();
}
```

I had considered it, but discarded it... `f` is also a template 
in our code. Your remark made me check again, and the call chain 
is short, perhaps I'll convert `f` to a template mixin... 
Unfortunately doesn't work: "immutable variable `aa` 
initialization is not allowed in nested function `f`".



-Johan



Re: Cast converts AA to rvalue?

2022-08-10 Thread ag0aep6g via Digitalmars-d-learn

On 10.08.22 10:20, Johan wrote:

```
shared immutable int[int] aa;
void main () {
     // (cast()aa)[1] = 1; // works without immutable
     (*cast(int[int]*)())[1] = 1;
}
```


We have shared static constructors for that:

shared static this()
{
aa[1] = 1; /* no cast needed */
}


Re: Cast converts AA to rvalue?

2022-08-10 Thread Johan via Digitalmars-d-learn
On Wednesday, 10 August 2022 at 00:28:53 UTC, Steven 
Schveighoffer wrote:

On 8/9/22 7:02 PM, Johan wrote:

Testcase:
```
shared int[int] aa;
void main () {
     cast()aa[1] = 1;
}
```

If you use `cast()(aa[1]) = 1`, it has a range error even on 
older versions.


That it ever worked is puzzling.


I think old compilers parsed it as `(cast()aa)[1]`, which works 
on newer compilers too without range error.


In my case, `aa` is also `immutable`. The only way I know how to 
make it work is now pretty ugly (casting away immutable should be 
ugly, so perhaps it's OK...):

```
shared immutable int[int] aa;
void main () {
// (cast()aa)[1] = 1; // works without immutable
(*cast(int[int]*)())[1] = 1;
}
```


Re: Cast converts AA to rvalue?

2022-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/22 7:02 PM, Johan wrote:

Testcase:
```
shared int[int] aa;
void main () {
     cast()aa[1] = 1;
}
```

Up to dlang 2.097, this program runs and works fine.
Since dlang 2.098, the program errors with:
`core.exception.RangeError@/app/example.d(3): Range violation`

I think the 2.098+ behavior is correct, but I cannot find anything about 
the change of this language behavior in the release notes.


So what is happening is you are casting away shared on the expression 
`aa[1]`. This expression by itself is an *access* of a value, not an 
*assignment*. This is consistent for structs defining both opIndex and 
opIndexAssign (the expression calls `opIndex`, not `opIndexAssign`), as 
far back as I can test.


If you use `cast()(aa[1]) = 1`, it has a range error even on older versions.

That it ever worked is puzzling.

-Steve


Cast converts AA to rvalue?

2022-08-09 Thread Johan via Digitalmars-d-learn

Testcase:
```
shared int[int] aa;
void main () {
cast()aa[1] = 1;
}
```

Up to dlang 2.097, this program runs and works fine.
Since dlang 2.098, the program errors with:
`core.exception.RangeError@/app/example.d(3): Range violation`

I think the 2.098+ behavior is correct, but I cannot find 
anything about the change of this language behavior in the 
release notes.


Please enlighten me,
  Johan

related discussion: 
https://forum.dlang.org/post/etxuhqzlkofitxsws...@forum.dlang.org