warning message about "operation may be undefined"

M

miloody

dear all:
below is my source code.
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
int index;
int idx0=0;
for(index=0;index<1024;index++)
{
idx0 = (++idx0)%2;
printf(" %d\n",idx0);
}
return 1;

}

and I compile it with following commands
"gcc -Wall -g -O1 -o test test.c"
but the warning say:
test.c: In function "main":
test.c:12: warning: operation on "idx0" may be undefined

I split it by line 10 and line 11, and they go fine.
why does the operation in line 12 get warning?

Thanks for your help in advance,
miloody
 
I

Ike Naar

idx0 = (++idx0)%2;

The ++ operator has a side effect that makes the statement undefined.
Since you're not making use of the side effect, you may as well remove
it and simply write:

idx0 = (idx0 + 1) % 2;
 
M

miloody

hi:
The ++ operator has a side effect that makes the statement undefined.
Since you're not making use of the side effect, you may as well remove
it and simply write:

        idx0 = (idx0 + 1) % 2;
why ++ makes the statement undefined?
what kind of side effect it will be if I use ++ before parameter?
thanks for your help,
miloody
 
A

Angel

hi:

why ++ makes the statement undefined?
what kind of side effect it will be if I use ++ before parameter?
thanks for your help,

The ++ operator has the side effect of assiging a new value to the
variable in the operant (namely the old value plus one). In the same
statement, you are also assigning an entirely new value to this same
variable. The result will depend on which assignment will be done first,
and there is no guarantee on which one will be done first, hence
undefined.
 
J

James Kuyper

hi:

why ++ makes the statement undefined?

Because it's in the same expression with the "=" operator, acting on the
same object, with no sequence points between them. The standard says
"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression".
Your statement modifies the value of idx0 twice, with no sequence points
anywhere except at the end of the statement.

One reason for this, is that the committee did not want the standard to
specify which order the two assignments occur in - they want to
discourage people from writing code like that. However, if that's all
that mattered, they could simply have left the order unspecified.

For example, in general it's possible that it takes multiple
instructions to update the value of an object (for instance, if it's a
64-bit type on an 8-bit processor). In that case, the instructions
implementing one modification of the object might be interleaved with
the ones that implement another; the result could be just about anything.
what kind of side effect it will be if I use ++ before parameter?
thanks for your help,

The C standard classifies the change in the value of idx0 as a
side-effect of the "++" operator. It's also a side-effect of the "="
operator. That may seem to be an odd way of thinking about things, since
that "side-effect" is normally the main reason for using an assignment
operator. However, that's the way the C standard describes these things.
As far as the standard is concerned, the "main effect" (a phrase never
used by the standard) of these expressions is to result in a value which
can be used in yet another expression.
 
B

Barry Schwarz

hi:

why ++ makes the statement undefined?
what kind of side effect it will be if I use ++ before parameter?
thanks for your help,

Others have explained the real issue. This is just a reminder that
the word parameter has a specific meaning (related to functions) which
is not relevant to the statement under discussion. In the expression
++idx, idx is the operand of the ++ operator, not a parameter. While
there was no confusion here, future discussions will benefit from
correct terminology.
 
M

miloody

hi all:
Million thanks for your kind and detail explanation.
per James's explanation:
"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression"

I have some question.
idx0 = (++idx0)%2;

Doesn't () make the sequence of how to evaluate the expression?
what I means is since (), (++idx0) will do first then %2 and finally
assigned the value to idx0, right?

Thanks for your help,
miloody
 
M

miloody

hi all:
Million thanks for your kind and detail explanation.
per James's explanation:
"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression"

I have some question.
idx0 = (++idx0)%2;

Doesn't () make the sequence of how to evaluate the expression?
what I means is since (), (++idx0) will do first then %2 and finally
assigned the value to idx0, right?

Thanks for your help,
miloody
 
W

Willem

miloody wrote:
) per James's explanation:
) "Between the previous and next sequence point an object shall have its
) stored value modified at most once by the evaluation of an expression"
)
) I have some question.
) idx0 = (++idx0)%2;
)
) Doesn't () make the sequence of how to evaluate the expression?

No, it only makes the precedence.

) what I means is since (), (++idx0) will do first then %2 and finally
) assigned the value to idx0, right?

Wrong.
It could very well do this:
- put idx0 into register a
- add 1 to register a
- put 1 into register b
- 'and' register a into register b
- store register b into idx0
- store register a into idx0


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
S

Seebs

Doesn't () make the sequence of how to evaluate the expression?

No.

Please read the FAQ.
what I means is since (), (++idx0) will do first then %2 and finally
assigned the value to idx0, right?

NO.

Parentheses are not sequence points. They do not order operations, they
group operands.

This is a FAQ. Please read it. Every question you have asked, and probably
every question you will ask during the next week or so of posts on this topic,
is answered there in great detail with beautiful examples and exceptionally
fine writing.

http://c-faq.com/

-s
 
J

James Waldby

.
int idx0=0; ....
idx0 = (++idx0)%2; ....
test.c:12: warning: operation on "idx0" may be undefined

Others mentioned the reason for the warning (two assignments
to idx0 without intervening sequence point) and Ike Naar
suggested writing
idx0 = (idx0 + 1) % 2;

A simpler way of toggling between 0 and 1, given that idx0
starts with value 0, is
idx0 = 1 - idx0;
 
L

lawrence.jones

James Waldby said:
A simpler way of toggling between 0 and 1, given that idx0
starts with value 0, is
idx0 = 1 - idx0;

Or, even simpler:

idx0 = !idx0;
 
B

Ben Bacarisse

James Waldby said:
Others mentioned the reason for the warning (two assignments
to idx0 without intervening sequence point) and Ike Naar
suggested writing
idx0 = (idx0 + 1) % 2;

A simpler way of toggling between 0 and 1, given that idx0
starts with value 0, is
idx0 = 1 - idx0;

I use idx0 = !idx0; which has the small advantage of not relying on the
initial value. Of course if you use idx0 before toggling it the initial
value does matter so there's not much in it.
 
B

Ben Pfaff

Ben Bacarisse said:
I use idx0 = !idx0; which has the small advantage of not relying on the
initial value. Of course if you use idx0 before toggling it the initial
value does matter so there's not much in it.

Yet another way:
idx0 ^= 1;
 

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
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top