[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

warning message about "operation may be undefined"

miloody

5/1/2011 9:33:00 AM

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
17 Answers

Ike Naar

5/1/2011 9:52:00 AM

0

On 2011-05-01, miloody <miloody@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

5/1/2011 9:57:00 AM

0

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

5/1/2011 10:07:00 AM

0

On 2011-05-01, miloody <miloody@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

5/1/2011 10:54:00 AM

0

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

5/1/2011 5:31:00 PM

0

On Sun, 1 May 2011 02:57:17 -0700 (PDT), miloody <miloody@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,

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

5/2/2011 5:19:00 AM

0

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

--
Peter

miloody

5/4/2011 1:54:00 PM

0

hi all:
Million thanks for your kind and detail explanation.
> 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/ieqiplusplu...
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

5/4/2011 1:58:00 PM

0

hi all:
Million thanks for your kind and detail explanation.
> 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/ieqiplusplu...
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

Willem

5/4/2011 2:01:00 PM

0

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

5/4/2011 3:32:00 PM

0

On 5/4/2011 9:54 AM, miloody wrote:
> hi all:
> Million thanks for your kind and detail explanation.
>> 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/ieqiplusplu...
> 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?

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