Comment #0 by john.loughran.colvin — 2020-06-22T11:15:09Z
void main()
{
int a;
static s = S!a();
s.bar();
}
struct S(alias q)
{
int b;
void bar()
{
b = q;
}
}
segfault reading q, it attempts to read address 0x8
same in all versions of dmd seen on run.dlang.io
Comment #1 by uplink.coder — 2020-06-22T11:31:38Z
I Assume:
this happens because `a` is a local t the frame of main.
when s.bar is called it uses the same offset but in the frame of bar.
My first solution would be to make it an error.
Comment #2 by simen.kjaras — 2020-06-22T12:17:35Z
I'm not sure this is exactly the same issue, but it's certainly analogous:
unittest {
import std.stdio;
int i;
writeln("Outside: ", &i);
static fn = (){
writeln("Inside: ", &i);
++i;
};
writeln("Context: ", fn.ptr);
fn();
}
Output:
Outside: 3100014
Context: null
Inside: 4
(0): [unittest] Access Violation
As we can see, the context pointer for the delegate is not initialized.
Making it compile would either be equivalent to making 'i' static, or have different behavior for the first and consequent calls, as only the first would have its 'i' modified by calls to fn().
Sensible workarounds do exist, this is most likely to be a mistake by the programmer, and having it work requires that this corner case be described somewhere. I say make it an error.
Comment #3 by simen.kjaras — 2020-06-22T12:18:58Z
(In reply to Simen Kjaeraas from comment #2)
> Making it compile
Ahem. Making it *work*.
Comment #4 by bugzilla — 2020-08-09T02:17:46Z
The compiler is attempting to produce a compile-time static initializer for main.s, using a value that only exists at runtime.
This is definitely accepts-invalid, not wrong-code.
Comment #5 by robert.schadek — 2024-12-13T19:09:37Z