Thread overview
aligned struct field weirdness
Jun 17
realhet
Jun 18
realhet
June 17

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.

June 18

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

June 18

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.

June 18

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.:

enum State {
   @"state2" state1,
   @"state1" state2
}

-Steve