www.digitalmars.com         C & C++   DMDScript  

D.gnu - Problem with passing ref parameters to properties

reply "SebastianA" <sebastian.ahlman remedygames.com> writes:
We are seeing a problem with passing ref parameters to 
properties. This bug only occurs in certain situations. Consider 
the following code:

====
void runTest()
{
	Thing t;
	t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3, 
3);
	Vec v = t.vPosition;

	outputDebug("%d %d\n", v.x, v.y);
}

struct Vec
{
	int x;
	int y;
}

struct Thing
{
	 property Vec vPosition() { return mPosition; }
	 property Vec vPosition( const ref Vec value ) { return 
mPosition = value; }

private:
	Vec mPosition;
}
===

Now, this code should output either "2 2" or "3 3" depending on 
the time. However, on release builds this code will output "0 0" 
every time it is run. This seems to happen regardless of the 
optimization level (we have tried with -O1 and -O3). Some things 
to note is that the bug will NOT occur if any of the following is 
true:

- We compile the code in debug mode. - We specify a constant 
known at compile time (eg. "true") instead of the 
non-deterministic time value. - We save the vector into a 
temporary local variable before passing it to the property. - We 
remove the "const ref" from the property setter and pass the 
vector by value.

Debugging the code reveals that the value passed to the getter is 
indeed 0,0, which rules out the getter as the error source.

We are building this on x64 Windows using gdc version 4.6.1 
20110627 (gdc hg r826:396ce79e6402(default), using dmd ) 
(tdm64-1).

Any idea what's going on?
May 10 2012
parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
On 10 May 2012 15:18, SebastianA <sebastian.ahlman remedygames.com> wrote:
 We are seeing a problem with passing ref parameters to properties. This b=
ug
 only occurs in certain situations. Consider the following code:

 =3D=3D=3D=3D
 void runTest()
 {
 =A0 =A0 =A0 =A0Thing t;
 =A0 =A0 =A0 =A0t.vPosition =3D (Clock.currStdTime % 2 =3D=3D 0) ? Vec(2, =
2) : Vec(3, 3);
 =A0 =A0 =A0 =A0Vec v =3D t.vPosition;

 =A0 =A0 =A0 =A0outputDebug("%d %d\n", v.x, v.y);
 }

 struct Vec
 {
 =A0 =A0 =A0 =A0int x;
 =A0 =A0 =A0 =A0int y;
 }

 struct Thing
 {
 =A0 =A0 =A0 =A0 property Vec vPosition() { return mPosition; }
 =A0 =A0 =A0 =A0 property Vec vPosition( const ref Vec value ) { return mP=
osition =3D
 value; }

 private:
 =A0 =A0 =A0 =A0Vec mPosition;
 }
 =3D=3D=3D

 Now, this code should output either "2 2" or "3 3" depending on the time.
 However, on release builds this code will output "0 0" every time it is r=
un.
 This seems to happen regardless of the optimization level (we have tried
 with -O1 and -O3). Some things to note is that the bug will NOT occur if =
any
 of the following is true:

 - We compile the code in debug mode. - We specify a constant known at
 compile time (eg. "true") instead of the non-deterministic time value. - =
We
 save the vector into a temporary local variable before passing it to the
 property. - We remove the "const ref" from the property setter and pass t=
he
 vector by value.

 Debugging the code reveals that the value passed to the getter is indeed
 0,0, which rules out the getter as the error source.

 We are building this on x64 Windows using gdc version 4.6.1 20110627 (gdc=
hg
 r826:396ce79e6402(default), using dmd ) (tdm64-1).

 Any idea what's going on?
Hello Sebastian, Thanks for your report. I will check this out and get back to you this afternoon. You should be able to produce a debug tree of the code generated in GCC AST using the command line switch -fdump-tree-original. This will output the code sent to the backend in a C-like syntax, and should help you decode where it may be going wrong. Have you also checked this test case against the DMD compiler to see if you get the same or different behaviour that GDC produces? Regards --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
May 10 2012
parent reply "SebastianA" <sebastian.ahlman remedygames.com> writes:
I had not tested the code with DMD. We need x64 support, so we 
need GDC for that at the moment. However, I tried compiling with 
DMD and it seems that the line

t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3, 
3);

does not compile with the latest DMD compiler. I get the error:

test.d(23): Error: not a property t.vPosition

when trying that. If I remove the ternary operator and just 
assign Vec(2, 2) to the property, it works as expected. Am I 
missing something here? Why cannot I write the code as listed 
above?
May 10 2012
next sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
SebastianA wrote:

 I had not tested the code with DMD. We need x64 support, so we
 need GDC for that at the moment. However, I tried compiling with
 DMD and it seems that the line
 
 t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3,
 3);
 
 does not compile with the latest DMD compiler. I get the error:
 
 test.d(23): Error: not a property t.vPosition
 
 when trying that. If I remove the ternary operator and just
 assign Vec(2, 2) to the property, it works as expected. Am I
 missing something here? Why cannot I write the code as listed
 above?
DMD has the -m64 switch for x86_64. AFAIK it produces 64bit executables even without it, on x86_64 machine. -- http://dejan.lekic.org
May 25 2012
parent Leandro Lucarella <luca llucax.com.ar> writes:
Dejan Lekic, el 25 de mayo a las 11:59 me escribiste:
 SebastianA wrote:
 
 I had not tested the code with DMD. We need x64 support, so we
 need GDC for that at the moment. However, I tried compiling with
 DMD and it seems that the line
 
 t.vPosition = (Clock.currStdTime % 2 == 0) ? Vec(2, 2) : Vec(3,
 3);
 
 does not compile with the latest DMD compiler. I get the error:
 
 test.d(23): Error: not a property t.vPosition
 
 when trying that. If I remove the ternary operator and just
 assign Vec(2, 2) to the property, it works as expected. Am I
 missing something here? Why cannot I write the code as listed
 above?
DMD has the -m64 switch for x86_64. AFAIK it produces 64bit executables even without it, on x86_64 machine.
No, the default architecture it's bounded to the architecture the compiler was compiled for. If DMD is compiled in 32bit, it will default to 32bit even on a x86_64 OS (at least in Linux). AFAIK it doesn't do any runtime checking at all for the arch. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Es mejor probar el sabor de sapo y darse cuenta que es feo, antes que no hacerlo y creer que es una gran gomita de pera. -- Dr Ricardo Vaporesso, Malta 1951
May 25 2012
prev sibling parent Trass3r <un known.com> writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8148
May 25 2012