The following simple code:
---
cat > app2.d << EOF
import core.atomic;
import std.stdio;
struct Test {
this(long v) {
val = v;
}
long val;
}
void main() {
shared(Test) test = Test(7);
auto buf = atomicLoad(test);
writefln("buf: %s, orig: %s", buf, cast(Test)test);
}
EOF
---
produces the following output:
buf: Test(0), orig: Test(7)
instead of the expected:
buf: Test(7), orig: Test(7)
Assembly with objdump -d -g -C -S -l app2.o (full output appended):
void main() {
0: 55 push %rbp
1: 48 8b ec mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
/home/robert/projects/phobosx/source/app2.d:11
shared(Test) test = Test(7);
8: 48 8d 45 f0 lea -0x10(%rbp),%rax <<<<< -0x10 is right
c: 48 31 c9 xor %rcx,%rcx
f: 48 89 08 mov %rcx,(%rax)
12: 48 be 07 00 00 00 00 movabs $0x7,%rsi
19: 00 00 00
1c: 48 89 c7 mov %rax,%rdi <<<< used here correctly
1f: e8 00 00 00 00 callq 24 <_Dmain+0x24>
24: 48 8d 75 f0 lea -0x10(%rbp),%rsi
/home/robert/projects/phobosx/source/app2.d:12
auto buf = atomicLoad(test);
28: 48 8d 7d f8 lea -0x8(%rbp),%rdi <<<< now -0x8, why?
2c: e8 00 00 00 00 callq 31 <_Dmain+0x31>
It seems that the wrong address gets passed to atomicLoad. If you remove the constructor of Test the right address (-0x10) is used. Various transformation of this program all have the same wrong output: You can make test global, put it in a union together with a plain long, create a non shared temporary before assigning to the shared variable, use casts, ... The only thing that helps is removing the constructor.
Comment #1 by jfanatiker — 2013-07-15T03:10:02Z
Created attachment 1233
Full assembly dump
Comment #2 by mxfomin — 2014-08-14T06:50:31Z
I remember Walter was speaking that atomicLoad is restricted only to POD structs and structs with constructors are not POD. So, it is clear why it is not working (it also explains observation that removing constructor fixes the problem).
Comment #3 by edwards.ac — 2017-05-10T01:08:47Z
Tested on 2017-05-10 with DMD v2.074.0 on both Ubuntu 16.04 and macOS Sierra. Produces the expected output on both systems:
buf: Test(7), orig: Test(7)
Comment #4 by ag0aep6g — 2019-08-18T23:25:27Z
(In reply to Andrew Edwards from comment #3)
> Tested on 2017-05-10 with DMD v2.074.0 on both Ubuntu 16.04 and macOS
> Sierra. Produces the expected output on both systems:
>
> buf: Test(7), orig: Test(7)
Apparently works since DMD 2.065. Closing as worksforme.