www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - aligned struct field weirdness

reply realhet <real_het hotmail.com> writes:
Hello,

I'm having a weird case of access violation.

I tried to narrow the problem and put up a reproducible testCase 
on compilerexploer, but it requires my framework too which 
overrides std.stdio.writeln() in order to produce colorful text, 
and logging, etc.

The error is an access violation when I access the struct in the 
f() function.

Sometimes it can be fixed (marked the place.)

In one sentence: It is an aligned struct field, whose struct is 
given to a class as a template parameter.

Maybe the weirdness is caused by the align(16)? When the fields 
of the struct are placed on the instance of the class?

I know it's not reproduceable, maybe it was a bug that had been 
already fixed.  So I only ask if the situation is familiar to 
someone, please tell me, what tricks I need to avoid.

I can avoid the align using dummy fields.
I can allocate the struct with new.
But it's a bummer, that the nicest version is unstable.

```
import het;

struct S
{
	int a;
	align(16)//<-this triggers it
	int[4] b;
}

class A(T)
{
	version(none)
	{ T u; }
	else
	{
		T* p; //<- this fixes it.  (The struct is not on the class 
surface)
		ref u() { return *p; }
		this() { p = new T; }
	}
}

class B: A!S
{ void f() { writeln(u.text/+<-The access violation can be 
here+/); } }

void main()
{
	//writeln("a"); <- this fixes it
	auto b = new B; //<-scoped! can trigger it too
	b.f;
}
```

Thank You in advance.
Jun 17
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 17 June 2024 at 19:45:18 UTC, realhet wrote:
 Hello,

 I'm having a weird case of access violation.
Often times, you are focused on something that isn't the problem, but *triggers* the problem. Not saying it's not a compiler error, it could be. But chances are pretty low. If you cannot get this to happen unless you use your custom writeln thing, I'd focus on trying to figure out if that custom writeln is doing something incorrect. All the code you posted here looks fine to me. It compiles and runs fine on run.dlang.io (even with the `version(none)` changed to `version(all)`, or using `scoped!B`). -Steve
Jun 17
parent reply realhet <real_het hotmail.com> writes:
On Tuesday, 18 June 2024 at 02:26:00 UTC, Steven Schveighoffer 
wrote:
 All the code you posted here looks fine to me. It compiles and 
 runs fine on run.dlang.io (even with the `version(none)` 
 changed to `version(all)`, or using `scoped!B`).
Thank You for checking. Also to add to the weirdness, this happens only with release build. I tried to narrow the problem, but I wasn't able, but I guess I've found another solution: There is a part in my framework which works with LDC2 1.28, but that's 'illegal' with later versions. That's why I'm stuck in the past, but now it adds more motivation to catch up with the latest version. That part declares an enum, whose members have UDA's pointing to the enum's members. With 2 step parsing it is valid, but later compiler versions don't like this. It's a quite big state machine graph, I have to refactor this to eliminate this self-referencing to catch up with the latest compiler. So now I have fixes that seem to be working, and soon with the latest compiler I will check it again, and hopefully the fixes aren't needed anymore.
Jun 18
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Tuesday, 18 June 2024 at 09:10:28 UTC, realhet wrote:
 I tried to narrow the problem, but I wasn't able, but I guess 
 I've found another solution: There is a part in my framework 
 which works with LDC2 1.28, but that's 'illegal' with later 
 versions.
Oh yeah. That is many versions ago! Released in 2021.
 That's why I'm stuck in the past, but now it adds more 
 motivation to catch up with the latest version.
Another motivation -- even if you found this was a bug and it is still in the latest compiler, the fix will go into the *latest compiler*, not the one that works with your code!
 That part declares an enum, whose members have UDA's pointing 
 to the enum's members.
 With 2 step parsing it is valid, but later compiler versions 
 don't like this.
 It's a quite big state machine graph, I have to refactor this 
 to eliminate this self-referencing to catch up with the latest 
 compiler.
Hm... a possibility is to change the UDAs to strings, and then post-process the strings into the actual members using `__traits(getMember, State, name)` So e.g.: ```d enum State { "state2" state1, "state1" state2 } ``` -Steve
Jun 18