++i

  • Thread starter Thread starter pneuvil1
  • Start date Start date
P

pneuvil1

Shouldn't this work in c++?

int i=0;
while (i < 35) databuffer = databuffer [++i];
databuffer [35] = x;

It does in CSharp.

here I am making room at the end of the buffer and then sticking a character
at the end. What happens is that the characters stuffed at the end never get
migrated down the buffer. It is as if the ++i is behaving like i++.

data buffer is declared like: char databuffer [36];
 
pneuvil1 said:
Shouldn't this work in c++?

No, the order of evaluation isn't defined in C++. You can't use i and
++i in the same expression.
int i=0;
while (i < 35) databuffer = databuffer [++i];
databuffer [35] = x;

It does in CSharp.

here I am making room at the end of the buffer and then sticking a
character at the end. What happens is that the characters stuffed
at the end never get migrated down the buffer. It is as if the ++i
is behaving like i++.

data buffer is declared like: char databuffer [36];


for (int i = 0; i != 35; ++i)
databuffer = databuffer[i + 1];



Bo Persson
 
Shouldn't this work in c++?

int i=0;
while (i < 35) databuffer = databuffer [++i];
databuffer [35] = x;

It does in CSharp.

What happens is that the characters stuffed at the end never get
migrated down the buffer. It is as if the ++i is behaving like i++.

data buffer is declared like: char databuffer [36];


How do you initialize the buffer? If there is a zero somewhere,
then the zero is pushed to the left, and if you printf the string
(or look at it in the debugger) the strings stops at the zero.

Imagine this:
'a' 'b' 'c' 'd' 'e' 0
pushback( 'w' )
the result is
'b' 'c' 'd' 'e' 0 'w'

So printf will show "bcde" (instead of "bcdew", that you expect)

In C the strings are zero-terminated, they are not like the C#
string class.
 
Oh, here is the problem:
databuffer = databuffer [++i];

This translates to
++i;
someRegistry = databuffer ;
databuffer = someRegistry;

So, really
++i;
databuffer = databuffer;

So really nothing gets moved around.

Your code is:
int i=0;
while (i < 35) databuffer = databuffer ;
databuffer [35] = x;

So effectively
databuffer [35] = x;
(the while does not count)
 
No, the order of evaluation isn't defined in C++. You can't use i and
++i in the same expression.

Of course it is, and of course you can.
the right side gets evaluated first, and the ++ happens before the result
is used to access the buffer.
 
Mihai said:
Of course it is, and of course you can.
the right side gets evaluated first, and the ++ happens before the
result is used to access the buffer.

No, definitely not. :-)

The assignment must be performed after evaluating both the left and
the right side, but there are no requirements for their order.

The result of ++i is used on the right side, but there is no
requirement that the new value is stored in i, until the end of the
statement (the semicolon).


http://publications.gbdirect.co.uk/c_book/chapter8/sequence_points.html



Bo Persson
 
Mihai N. said:
Of course it is, and of course you can.
the right side gets evaluated first, and the ++ happens before the result
is used to access the buffer.

Which is *not* what happens when the OP's code runs. I think Bo hit it on
the head.
 
The result of ++i is used on the right side, but there is no
requirement that the new value is stored in i, until the end of the
statement (the semicolon).

===========
; 6 : int i=0;

mov DWORD PTR _i$[ebp], 0
$LN2@main:

; 7 : while (i < 35) databuffer = databuffer [++i];

cmp DWORD PTR _i$[ebp], 35 ; 00000023H
jge SHORT $LN1@main
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
mov ecx, DWORD PTR _i$[ebp]
mov edx, DWORD PTR _i$[ebp]
mov al, BYTE PTR _databuffer$[ebp+edx]
mov BYTE PTR _databuffer$[ebp+ecx], al
jmp SHORT $LN2@main
$LN1@main:

; 8 : databuffer [35] = x;

mov cl, BYTE PTR _x$[ebp]
mov BYTE PTR _databuffer$[ebp+35], cl
===========

See here:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax

That's exactly what is happening, i is incremented and stored back.


That tells that "you don't know when the effect of the increment on i
occurs."
It is indeed undefined by the standard. Meaning that different compilers
might behave differently, so you should not rely on it happening.

But VC does what I said, and that's the explanation for the behavior.

Now, another compiler (or even VS with other optimization settings)
might behave differently, so one should not program that way.
 
No, the order of evaluation isn't defined in C++. You can't use i and
Of course it is, and of course you can.
the right side gets evaluated first, and the ++ happens before the result
is used to access the buffer.

Ok, I see where the missunderstanding started.
I was thinking about what happens, while Bo was saying what is *guaranteed*
to happen, by the standard.
 
In this case, I wasn't concerned about printing the data in the string. It
served as a temporary buffer to process a very long string where I need to
look at 35 characters at a time and then then shift one character to the
right in the long string and look at that as a unit of 35.

Thanks for everyone's input.

Mihai N. said:
Shouldn't this work in c++?

int i=0;
while (i < 35) databuffer = databuffer [++i];
databuffer [35] = x;

It does in CSharp.

What happens is that the characters stuffed at the end never get
migrated down the buffer. It is as if the ++i is behaving like i++.

data buffer is declared like: char databuffer [36];


How do you initialize the buffer? If there is a zero somewhere,
then the zero is pushed to the left, and if you printf the string
(or look at it in the debugger) the strings stops at the zero.

Imagine this:
'a' 'b' 'c' 'd' 'e' 0
pushback( 'w' )
the result is
'b' 'c' 'd' 'e' 0 'w'

So printf will show "bcde" (instead of "bcdew", that you expect)

In C the strings are zero-terminated, they are not like the C#
string class.
 
Back
Top