Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

warning message about "operation may be undefined"

33 views
Skip to first unread message

miloody

unread,
May 1, 2011, 5:33:24 AM5/1/11
to
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

Ike Naar

unread,
May 1, 2011, 5:52:16 AM5/1/11
to
On 2011-05-01, miloody <mil...@gmail.com> wrote:
> 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;

miloody

unread,
May 1, 2011, 5:57:17 AM5/1/11
to
hi:
On May 1, 5:52 pm, Ike Naar <i...@iceland.freeshell.org> wrote:

> On 2011-05-01, miloody <milo...@gmail.com> wrote:
>
> >         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;
why ++ makes the statement undefined?
what kind of side effect it will be if I use ++ before parameter?
thanks for your help,
miloody

Angel

unread,
May 1, 2011, 6:07:28 AM5/1/11
to
On 2011-05-01, miloody <mil...@gmail.com> wrote:
> hi:

> On May 1, 5:52?pm, Ike Naar <i...@iceland.freeshell.org> wrote:
>> On 2011-05-01, miloody <milo...@gmail.com> wrote:
>>
>> > ? ? ? ? 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;

> 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.


--
The perfected state of a spam server is a smoking crater.
- The Crater Corollary to Rule #4

James Kuyper

unread,
May 1, 2011, 6:54:01 AM5/1/11
to
On 05/01/2011 05:57 AM, miloody wrote:
> hi:
> On May 1, 5:52�pm, Ike Naar <i...@iceland.freeshell.org> wrote:
>> On 2011-05-01, miloody <milo...@gmail.com> wrote:
>>
>>> � � � � 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;
> 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.
--
James Kuyper

Barry Schwarz

unread,
May 1, 2011, 1:31:23 PM5/1/11
to
On Sun, 1 May 2011 02:57:17 -0700 (PDT), miloody <mil...@gmail.com>
wrote:

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.

--
Remove del for email

Peter Nilsson

unread,
May 2, 2011, 1:19:21 AM5/2/11
to
miloody <milo...@gmail.com> wrote:
>         idx0 = (++idx0)%2;
> ...

> test.c:12: warning: operation on "idx0" may be undefined
> ...

> why does the operation in line 12 get warning?

This is a FAQ: <http://c-faq.com/expr/ieqiplusplus.html>

--
Peter

miloody

unread,
May 4, 2011, 9:54:25 AM5/4/11
to
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

miloody

unread,
May 4, 2011, 9:57:48 AM5/4/11
to
hi all:
Million thanks for your kind and detail explanation.

Willem

unread,
May 4, 2011, 10:00:41 AM5/4/11
to
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

Kenneth Brody

unread,
May 4, 2011, 11:32:00 AM5/4/11
to

The parentheses do not introduce what is known as a "sequence point". There
is no requirement that the increment of idx0 be done prior to performing the
"%" operator. Nor is there any requirement that it be done prior to the
assignment. The only requirement is that it be done prior to the next
"sequence point" which, in this case, is the ";" at the end of the
statement, and that the value of "++idx0" be one more than the current value
of idx0.

In other words, "++idx0" does _not_ mean "increment the value of idx0, and
then use that new value". Rather, it means "idx0 will be incremented prior
to the next sequence point, and the value to be used here is the value that
will be in idx0 after the increment".

What's the difference? Well, in a well-defined statement (of which this is
not), there is no observable difference. However, a compiler may find that
it can generate "better" code by delaying the increment, or even doing the
increment earlier. Or, worse still (as far as this UB is concerned), do the
increment and the assignment in parallel.

People often think of the parentheses as "forcing" the "order of
evaluation". However, it does not. It simply overrides the default
precedence of the operators in the statement. For example:

foo = ( ++a + b ) * a;

This is undefined for the same basic reasons as your statement. The
parentheses around "( ++a + b )" do _not_ force it do be evaluated prior to
the "a" outside the parentheses. Again, the order of evaluation is unspecified.

--
Kenneth Brody

Seebs

unread,
May 4, 2011, 11:54:05 AM5/4/11
to
On 2011-05-04, miloody <mil...@gmail.com> wrote:
> 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
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Peter Nilsson

unread,
May 4, 2011, 8:55:36 PM5/4/11
to
miloody <milo...@gmail.com> wrote:
> Peter Nilsson wrote:
> > ...

> > This is a FAQ: <http://c-faq.com/expr/ieqiplusplus.html>
>
> 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.

Still FAQs:

<http://c-faq.com/expr/precvsooe.html>
<http://c-faq.com/expr/seqpoints.html>

--
Peter

miloody

unread,
May 4, 2011, 11:03:02 PM5/4/11
to
Hi all:
I will check the FAQ first, sorry for bothering you.
Thanks a lot,
miloody

James Waldby

unread,
May 6, 2011, 2:36:09 PM5/6/11
to
On Sun, 01 May 2011 02:33:24 -0700, miloody wrote:
...
> 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;

--
jiw

Ben Bacarisse

unread,
May 6, 2011, 5:05:27 PM5/6/11
to
James Waldby <n...@valid.invalid> writes:

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.

--
Ben.

Ben Pfaff

unread,
May 6, 2011, 5:16:36 PM5/6/11
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> James Waldby <n...@valid.invalid> writes:
>> 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.

Yet another way:
idx0 ^= 1;
--
"It wouldn't be a new C standard if it didn't give a
new meaning to the word `static'."
--Peter Seebach on C99

lawrenc...@siemens.com

unread,
May 6, 2011, 4:37:30 PM5/6/11
to
James Waldby <n...@valid.invalid> wrote:
>
> 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;
--
Larry Jones

I kind of resent the manufacturer's implicit assumption
that this would amuse me. -- Calvin

0 new messages