array variable subscript generate wrong code (2008) ?

  • Thread starter Thread starter brof777
  • Start date Start date
B

brof777

here is the code:
DWORD SomeFunction(DWORD Dw_0, DWORD Dw_1, DWORD Dw_2)
{
return Dw_0 + Dw_1 + Dw_2;
}
void main()
{
DWORD Dw = 0;
DWORD pDw[3] = {1,2,3};
DWORD Dw_Sum = SomeFunction(pDw[Dw++], pDw[Dw++], pDw[Dw++]);
}
I expected VC++ 2008 generate code as SomeFunction(3,2,1) or
SomeFunction(1,2,3), however, the real code is like
SomeFunction(1,1,1)
I debug the and watch assembly code, find the code was generated with
push pDw[0] 3 times, then increase Dw by 3 times.
Can anyone tell me why?
 
here is the code:
DWORD SomeFunction(DWORD Dw_0, DWORD Dw_1, DWORD Dw_2)
{
return Dw_0 + Dw_1 + Dw_2;
}
void main()
{
DWORD Dw = 0;
DWORD pDw[3] = {1,2,3};
DWORD Dw_Sum = SomeFunction(pDw[Dw++], pDw[Dw++], pDw[Dw++]);
}
I expected VC++ 2008 generate code as SomeFunction(3,2,1) or
SomeFunction(1,2,3), however, the real code is like
SomeFunction(1,1,1)
I debug the and watch assembly code, find the code was generated with
push pDw[0] 3 times, then increase Dw by 3 times.
Can anyone tell me why?

This code has undefined behaviour, Dw++ is executed three times but it
is not defined when exactly that happens. This is quite classic example
like x = i++ + i++;

br
ismo
 
here is the code:
DWORD SomeFunction(DWORD Dw_0, DWORD Dw_1, DWORD Dw_2)
{
        return Dw_0 + Dw_1 + Dw_2;}

void main()
{
        DWORD Dw = 0;
        DWORD pDw[3] = {1,2,3};
        DWORD Dw_Sum = SomeFunction(pDw[Dw++], pDw[Dw++], pDw[Dw++]);}

I expected VC++ 2008 generate code as SomeFunction(3,2,1) or
SomeFunction(1,2,3), however, the real code is like
SomeFunction(1,1,1)
I debug the and watch assembly code, find the code was generated with
push pDw[0] 3 times, then increase Dw by 3 times.
Can anyone tell me why?

Because the behaviour of this code is undefined, according to the C++
standard : The post-increment of the "++" operator is a side-effect
of this operator (whose "main" effect is to return the value of Dw).
This side-effect should be applied at the next "sequence point" (in
standardese speaking) after the expression. Now, in your case, the
next sequence point is the call to SomeFunction, *after* evaluation of
all it's arguments.

What it means is that :
- the compiler is free to evaluate the arguments of SomeFunction in
any order (right to left, left to right, somehing else...).
- if the evaluation of those arguments have side-effect (which is your
case), those side-effect must be applied before the function is
called. However, exactly WHEN is undefined. The compiler is free to
apply them after evaluating all arguments (whis is obviously the
case), of after each argument evaluation, or anything else.

Conclusion : Never use several operations with side-effect in the same
expression : this is :
1) hardly readeable
2) undefined as far as the standard goes.

Arnaud
 
here is the code:
DWORD SomeFunction(DWORD Dw_0, DWORD Dw_1, DWORD Dw_2)
{
return Dw_0 + Dw_1 + Dw_2;
}
void main()
{
DWORD Dw = 0;
DWORD pDw[3] = {1,2,3};
DWORD Dw_Sum = SomeFunction(pDw[Dw++], pDw[Dw++], pDw[Dw++]);
}
I expected VC++ 2008 generate code as SomeFunction(3,2,1) or
SomeFunction(1,2,3), however, the real code is like
SomeFunction(1,1,1)
I debug the and watch assembly code, find the code was generated with
push pDw[0] 3 times, then increase Dw by 3 times.
Can anyone tell me why?

brof:

Please don't multi-post. This question has nothing to do with .NET, so it should
not be here anyway.
 
Back
Top