i++ question

B

Bo Sun

hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

for (i = 0; i < 3; i ++)
printf("a[%d]: %d, b[%d]: %d\n", i, a, i, b);


what is the output?

I run it under two different platform, linux and irix, and get two
different output. Can someone tell me why?

many thanks,

bo
 
M

Mark A. Odell

hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

You cannot do this! Use two different indexes and avoid the undefined
behavior. Please read the FAQ on this.
 
E

Ed Morton

Bo said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];
Note^

for (i = 0; i < 3; i ++)
printf("a[%d]: %d, b[%d]: %d\n", i, a, i, b);


what is the output?

I run it under two different platform, linux and irix, and get two
different output. Can someone tell me why?


There are no intermediate sequence points in the array assignment for
"a[i++] = b[i++]". See
http://publications.gbdirect.co.uk/c_book/chapter8/sequence_points.html
for details.

Ed.
 
F

Fred L. Kleinschmidt

Bo said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

for (i = 0; i < 3; i ++)
printf("a[%d]: %d, b[%d]: %d\n", i, a, i, b);

what is the output?

I run it under two different platform, linux and irix, and get two
different output. Can someone tell me why?

many thanks,

bo


THIS IS PROBABLY THE MOST COMMON QUESTION IN THIS NEWSGROUP.
Using the ++ or -- operator on the same variable more than once in the
same expression or statement causes undefined behavior. What did you
think would happen? When should i be incremented?
 
J

John Bode

Bo Sun said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

for (i = 0; i < 3; i ++)
printf("a[%d]: %d, b[%d]: %d\n", i, a, i, b);


what is the output?

I run it under two different platform, linux and irix, and get two
different output. Can someone tell me why?

many thanks,

bo


It's important to know how the ++ and -- operators actually work. The
expression

i++

evaluates to the current value of i, and as a side effect the variable
i is incremented by one. However, it is not required that the side
effect be applied immediately, only that it be applied before the next
sequence point (check your handy C reference for an explanation of
sequence points; if it doesn't mention sequence points, chuck it in
favor of a better one). For example, given the statement

k = i++ * j++;

the compiler may defer incrementing i and j until after completing the
multiplication and assignment. Or it may increment i and j
immediately after they are evaluated. Or it may do something else.
Here are two of several possible orders of operation:

Option 1 Option 2
-------- --------
t1 <- i t1 <- i
i <- i + 1 t2 <- j
t2 <- j k <- t1 * t2
j <- j + 1 i <- i + 1
k <- t1 * t2 j <- j + 1

In option 1, the side effects are applied immediately. In option 2,
they're deffered until after all the other operations are done.
Therefore, if you try to apply one of these operators to a variable
more than once between sequence points, there's no telling what you'll
get. The behavior is undefined.
 
C

CBFalconer

Mark A. Odell said:
Bo Sun said:
please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};
int i;

i = 0;
a[i++] = b[i++];

You cannot do this! Use two different indexes and avoid the
undefined behavior. Please read the FAQ on this.

<nit>
You hit another of my raw spots. s/cannot/may not/
</nit>

Note: He just did it.
 
A

Arthur J. O'Dwyer

Mark A. Odell said:
Bo Sun said:
a[i++] = b[i++];

You cannot do this!

<nit>
You hit another of my raw spots. s/cannot/may not/
</nit>

Note: He just did it.

Yes, but what's the use of being so vague as to say,
"You *may* not do this"? Any child could tell you he
*may* not do it -- but then again it *may* be the case
that he does do it...
s/may not/should not/ and avoid all ambiguity.
Or s/should not/must not/ and retain the original sense,
at the price of sounding like an English nanny. ;)

-Arthur
 
J

JV

Mark A. Odell said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

You cannot do this! Use two different indexes and avoid the undefined
behavior. Please read the FAQ on this.
Hi,
if I compile the above code with gcc -Wall -ansi -pedantic I get warning
that the "operation on i may be undefined", which is just fine. But why it
is said that "may be undefined" when C standard says that it is undefined?
And if compiler can detect undefined behaivour, shouldn't it report error,
not warining?
-Jyrki
 
J

Joona I Palaste

JV said:
Mark A. Odell said:
Bo Sun said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

You cannot do this! Use two different indexes and avoid the undefined
behavior. Please read the FAQ on this.
Hi,
if I compile the above code with gcc -Wall -ansi -pedantic I get warning
that the "operation on i may be undefined", which is just fine. But why it
is said that "may be undefined" when C standard says that it is undefined?
And if compiler can detect undefined behaivour, shouldn't it report error,
not warining?

First, undefined behaviour does not have to be erroneous code.
"Undefined behaviour" means behaviour which the standard does not
define, and does not require the implementation to define. It *allows*
the implementation to define it, however.
Strictly speaking, all OS-specific code causes undefined behaviour.
If it was erroneous code, C would be quite useless in OS-specific
applications, don't you think?
Second, the standard only mandates a diagnostic. It does not mandate
the content of that diagnostic. Therefore "The behaviour is undefined",
"The behaviour may be undefined", "You have roused the nasal daemons",
or "Pee Wee Herman for President in 2004!" are all standard-compliant
diagnostics for a[i++]=b[i++].
 
C

Christian Bau

Bo Sun said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

for (i = 0; i < 3; i ++)
printf("a[%d]: %d, b[%d]: %d\n", i, a, i, b);


what is the output?

I run it under two different platform, linux and irix, and get two
different output. Can someone tell me why?


Throw away the outputs that you got, then think about the problem and
try to find out what output you expect and why you expect it. If you
have a problem figuring out what the output should be then think about
why there is a problem and you will learn something.
 
K

Kevin Bracey

In message <[email protected]>
"JV said:
Hi,
if I compile the above code with gcc -Wall -ansi -pedantic I get warning
that the "operation on i may be undefined", which is just fine. But why it
is said that "may be undefined" when C standard says that it is undefined?

Maybe the compiler's not sure that the code actually is undefined behaviour.
That's the likely case for a lot of things declared as "undefined behaviour".
If they were easy to check for at compile time, they would probably have been
made constraints requiring diagnostics.
And if compiler can detect undefined behaivour, shouldn't it report error,
not warining?

Arguably, yes, to improve the quality of implementation. But it could only
do this if it was _certain_ it had seen undefined behaviour, otherwise it
would be in danger of rejecting valid code.

For example, my compiler only gives warnings for such things as "xxx may be
used before being set", which it can't always be certain about, but an error
for "narrow type supplied to va_arg".
 
M

Mark A. Odell

<nit>
You hit another of my raw spots. s/cannot/may not/
</nit>

Note: He just did it.

True, for permission "he may not do it" for possible actions "he can do
it" but of course he shouldn't.
 
F

Floyd Davidson

Joona I Palaste said:
JV said:
Mark A. Odell said:
hi:

please take a look at the following code:

int a[3] = {1, 3, 2};
int b[3] = {7, 9, 10};

int i;

i = 0;
a[i++] = b[i++];

You cannot do this! Use two different indexes and avoid the undefined
behavior. Please read the FAQ on this.
Hi,
if I compile the above code with gcc -Wall -ansi -pedantic I get warning
that the "operation on i may be undefined", which is just fine. But why it
is said that "may be undefined" when C standard says that it is undefined?
And if compiler can detect undefined behaivour, shouldn't it report error,
not warining?

First, undefined behaviour does not have to be erroneous code.
"Undefined behaviour" means behaviour which the standard does not
define, and does not require the implementation to define. It *allows*
the implementation to define it, however.
Strictly speaking, all OS-specific code causes undefined behaviour.
If it was erroneous code, C would be quite useless in OS-specific
applications, don't you think?
Second, the standard only mandates a diagnostic. It does not mandate
the content of that diagnostic. Therefore "The behaviour is undefined",
"The behaviour may be undefined", "You have roused the nasal daemons",
or "Pee Wee Herman for President in 2004!" are all standard-compliant
diagnostics for a[i++]=b[i++].

I don't believe the standard mandates any diagnostic for undefined
behavior in general, or for that particular example in specific.

Of course it allows a diagnostic for virtually anything...
 
M

Mark McIntyre

Yes, but what's the use of being so vague as to say,
"You *may* not do this"? Any child could tell you he
*may* not do it -- but then again it *may* be the case
that he does do it...

I believe "May" as a verb has two meanings.
One of them ,the one that CBF was using, means to permit. One tells a
child "you may not pour coffee in Granny's ear" meaning that you are
forbidden from doing it.

The other, the one you're using, is used to mean that a choice exists,
and the decision is not taken as to which choice is chosen. One tells
a child "If you're good we may go to the park", meaning that a
decision is yet to be taken.

s/may not/should not/ and avoid all ambiguity.
Or s/should not/must not/ and retain the original sense,
at the price of sounding like an English nanny. ;)

Yes'm.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top