This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: warning: operation on 'zero' may be undefined


Thanks, reviewed the faq, unfortunately question 3.3 specifies

 int i = 3 ;
 i = i++ ;

as having undefined behavior, erroneously referencing

 a[i] = i++ ;

as being similarly undefined, which it is; but that's because the value
of the index i is ambiguous as it's value is sensitive to the order
of lhs/rhs evaluation; which i = i++ is not.

And ironically, the ANSI/ISO C specification of a sequence point referred
to in question 3.8 as being:

   "Between the previous and next sequence point an object shall have its
    stored value modified at most once by the evaluation of an expression.
    Furthermore, the prior value shall be accessed only to determine the
    value to be stored."

Would seem to even further disambiguates the expression like i = ++i if i
were declared as volatile, as it specifies that i will be at most read and
written once, therefore:

 volatile int i = 3 ;
 i = ++i ;

must then arguably then be interpreted as:

 i = (temp = i + 1), temp ;

inhibiting it's intermediate assignment to i implied by it's rhs ++i.

I strongly suspect that the standard is being misinterpreted as it applies
to expressions like i = ++i ; which are in fact insensitive to their
sub-expression evaluation order; and being confused with expressions like
x[i] = ++i ; or ++i = i ; which are.

-paul-

Nathan Sidwell wrote:
> There is a good description at http://www.eskimo.com/~scs/C-faq/s3.html

Paul Schlie wrote:
> Upon further thought, it seems that C only specifies that the order of
> evaluation is unspecified for equivalent precedent sub-expression operations;
> as such, although:
> 
> ++x = x ;
> 
> is ambiguous, as the value of the rhs x may be evaluated prior to, or
> following it's increment on the lhs of the assignment expression; however
> 
> x = ++x ;
> 
> is not, as it the value of the rhs of the expression is insensitive to the the
> order of evaluation of the lhs, and visa-versa.
> 
> -paul-
> 
> 
> Robert Dewar wrote:
>> It's a matter of language definition, there simply is a requirement in the
>> C definition that the increment of zero take place before or after the
>> assignment. You are missing a required sequence point. Basically the rule in
>> C is that if you have an expression (remember that an assignment is just an
>> expression), and somewhere in that expression, you use an increment operator
>> on a variable, you can't mention that variable elsewhere in the expression.
>> End of story.
> 
> Paul Schlie wrote:
>> I guess I naively perceived the precedence rules unambiguously specified that
>> the the value of (++zero) % 3 would be evaluated prior to it's assignment as
>> % 
>> has a higher precedence than =, and correspondingly (++zero) was specified to
>> be evaluated prior to % as () has a higher precedence than %; as such
>> although 
>> zero = ++zero may be ambiguous, zero = (++zero) is not, therefore nor would
>> zero = (++zero) % 3; ?
>> 
>> Thanks, -paul-
>> 
>> Paul Schlie wrote:
>>> For my own edification, it's not clear to me that the instruction sequence:
>>> 
>>>  int zero = 125;
>>>  zero = (++zero)%3;
>>> 
>>> is ambiguous in any way, as I was under the impression that the left hand
>>> side 
>>> of an assignment expression will be assigned the resulting value of the
>>> evaluation of it's right hand side, which unambiguously logically equivalent
>>> to:
>>> 
>>> int zero = 125;
>>> zero = ((zero = zero + 1) % 3) ;
>>> 
>>> Where the compiler would hopefully recognize the opportunity to eliminate
>>> the 
>>> unnecessary intermediate assignment of zero = zero + 1, as zero is not
>>> declared as being volatile, nor implied due to a lack of a sequence point.
>>> 
>>> What am I missing?
>>> 
>>> Thanks, -paul-
>>> 
>>> On Friday 01 October 2004 03:57, Mathieu Malaterre wrote:
>>>>  I am trying gcc4, and turning -Wall reveal a strange warning:
>>>> 
>>>> int main()
>>>> {
>>>>    int zero = 125;
>>>>    zero = (++zero)%3;
>>>> }
>>>> 
>>>> g++ -Wall foo.cxx
>>>> 
>>>> foo.cxx: In function `int main()':
>>>> foo.cxx:4: warning: operation on 'zero' may be undefined
>>>> 
>>>> What does this mean ?
>>> 
>>> Paul Brook wrote:
>>> 
>>>> You incrementing and assigning to the same variable in one statement, which
>>>> invokes undefined behaviour.
>>> 
>>>> The code you wrote can be interpreted as
>>>> zero = zero%3;
>>>> or
>>>> zero = (zero % 3) + 1
>>>> or possibly even something entirely different.
>>> 
>>> Dave Korn wrote:
>>> 
>>>> I'm nitpicking, but considering it's a pre-increment, I'd have said
>>>> 
>>>> zero = (zero + 1) % 3;
>>>> or
>>>> zero = zero + 1;
>>>> 
>>>> were the interpretations.  And the problem is the lack of a sequence point
>>>> between them.
>>> 
>>> Giovanni Bajo wrote:
>>>> The error message could use a clarification though.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]