View mode: basic / threaded / horizontal-split · Log in · Help
May 10, 2012
Problem with passing ref parameters to properties
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
Re: Problem with passing ref parameters to properties
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
Re: Problem with passing ref parameters to properties
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
Re: Problem with passing ref parameters to properties
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
Re: Problem with passing ref parameters to properties
http://d.puremagic.com/issues/show_bug.cgi?id=8148
May 25, 2012
Re: Problem with passing ref parameters to properties
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
Top | Discussion index | About this forum | D home