Thread overview
Problem with passing ref parameters to properties
May 10, 2012
SebastianA
May 10, 2012
Iain Buclaw
May 10, 2012
SebastianA
May 25, 2012
Dejan Lekic
May 25, 2012
Leandro Lucarella
May 25, 2012
Trass3r
May 10, 2012
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
On 10 May 2012 15:18, SebastianA <sebastian.ahlman@remedygames.com> wrote:
> 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?


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
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
May 10, 2012
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 25, 2012
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
http://d.puremagic.com/issues/show_bug.cgi?id=8148
May 25, 2012
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