Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why is this expression detected as undefined by GCC, Splint?

Reply
Thread Tools

Why is this expression detected as undefined by GCC, Splint?

 
 
Tim Rentsch
Guest
Posts: n/a
 
      01-02-2011
Eric Sosman <(E-Mail Removed)> writes:

> On 12/30/2010 1:50 AM, amuro wrote:
>> Hi, I wonder why the following expression is detected as undefined
>> expression. In my opinion, this is a "defined" expression.
>>
>> x = *(x++, p); // line 21

>
> Undefined behavior: `x' is modified twice without an intervening
> sequence point.


No, the sequence point of the comma operator must precede the
evaluation of the assignment operation.

> Yes, there's a sequence point between `x++' and `p'. But there's
> no sequence point between `x=' and `x++'.


Of course there is, just as there is for

x = f( x++ );
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      01-02-2011
amuro <(E-Mail Removed)> writes:

> Hi, I wonder why the following expression is detected as undefined
> expression. In my opinion, this is a "defined" expression.
>
> x = *(x++, p); // line 21
>
> $ gcc -Wsequence-point test.c
> test.1:21: warning: operation on 'x' may be undefined


I suspect this comes from 'x' being incremented before being
assigned a value. Was 'x' initialized?

> $ splint test.c
> test.c:21:6: Expression has undefined behavior (value of left operand
> x is modified by right operand *(x++, p)): x = *(x++, p)


Splint is broken. The 'x++' being before a comma operator of a RHS
subexpression of the assignment, the increment of 'x' must be complete
before the assignment operation is initiated.

> Another expression looks similar with previous expression shows
> expected result by GCC but not Splint. That means GCC does not
> consider it as undefined but Splint considers it as undefined
> expression.
>
> x = (x++, y); // line 19
>
> $ splint test.c
> test.c:19:6: Expression has undefined behavior (value of left operand
> x is modified by right operand (x++, y)): x = (x++, y)


Splint is broken here also.
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      01-02-2011
On 2011-01-02, Tim Rentsch <(E-Mail Removed)> wrote:
> Ike Naar <(E-Mail Removed)> writes:
>> with behaviour identical to the well-defined ``x = *p; x++;'' .

>
> This statement is not correct. The expression 'lhs x' is
> not affected by 'x++' so it doesn't matter whether 'x++'
> is evaluated before or after 'lhs x'.


You're correct, x's value is irrelevant for ``lhs x'' because
lhs x is only written to. My bad.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      01-02-2011
On 2011-01-02, Tim Rentsch <(E-Mail Removed)> wrote:
> Seebs <(E-Mail Removed)> writes:
>> Well, yes. That's one of the points of the revision. However, in some
>> cases, it will make a thing clear which *isn't true* in the old document.


> Except in this case the point made clear _is_ true in the old
> document. And C89 as well.


Is it? I was under the impression that consensus was that, even though
it's obvious what "should" happen, an assignment to something which is
also modified during evaluation of the value to be assigned was undefined
behavior because the same object could in theory be modified twice between
sequence points, because assignment wasn't formally specified to imply
sequencing.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
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.
 
Reply With Quote
 
Tom St Denis
Guest
Posts: n/a
 
      01-03-2011
On Dec 30 2010, 3:38*am, Stephen Sprunk <(E-Mail Removed)> wrote:
> On 30 Dec 2010 01:51, (E-Mail Removed) wrote:
>
>
>
>
>
>
>
>
>
> > On Dec 30, 1:06 am, amuro <(E-Mail Removed)> wrote:
> >> On 12월30일, 오후4시00분, Nick Keighley <(E-Mail Removed)>
> >> wrote:

>
> >>> On Dec 30, 6:50 am, amuro <(E-Mail Removed)> wrote:

>
> >>>> Hi, I wonder why the following expression is detected as undefined
> >>>> expression. In my opinion, this is a "defined" expression.

>
> >>>> x = *(x++, p); *// line 21

>
> >>>> $ gcc -Wsequence-point test.c
> >>>> test.1:21: warning: operation on 'x' may be undefined

>
> >>>> $ splint test.c
> >>>> test.c:21:6: Expression has undefined behavior (value of left operand
> >>>> x is modified by right operand *(x++, p)): x = *(x++, p)

>
> >>>> Another expression looks similar with previous expression shows
> >>>> expected result by GCC but not Splint. That means GCC does not
> >>>> consider it as undefined

>
> >>> it may be that gcc does not *detect* that it is undefined. A compiler
> >>> is not obliged to diagnose undefined behaviour. A compiler isn't
> >>> obliged to do *anything* specific with undefined behaviour. After all
> >>> the behaviour is not defined...

>
> >> Thank you for reply. You're right that a compiler is not obliged to
> >> diagnose undefined behaviour.
> >> I'd like to change my question. Does the expression, "x = *(x++, p);"
> >> result in undefined behavior in terms of C Specification?

>
> > Yes. *You cannot modify a variable twice between sequence points,
> > since there is no order defined. *IOW, "*(x++, p)" may be reasonably
> > defined, but the time at which the ++ happens relative to the
> > assignment into x is *not*.

>
> The comma's introduces a sequence point between the evaluations of x++
> and p, and the assignment cannot be evaluated until after p is
> evaluated, so how is the behavior undefined? *AFAICT, that expression
> must have identical behavior to the well-defined "x++; x = *p;".


I thought the order of eval of comma expressions is not defined. So
it could be x = *p; x++; as well.

Tom
 
Reply With Quote
 
David Resnick
Guest
Posts: n/a
 
      01-03-2011
On Jan 3, 7:41*am, Tom St Denis <(E-Mail Removed)> wrote:
> On Dec 30 2010, 3:38*am, Stephen Sprunk <(E-Mail Removed)> wrote:
>
>
>
> > On 30 Dec 2010 01:51, (E-Mail Removed) wrote:

>
> > > On Dec 30, 1:06 am, amuro <(E-Mail Removed)> wrote:
> > >> On 12월30일, 오후4시00분, Nick Keighley <(E-Mail Removed)>
> > >> wrote:

>
> > >>> On Dec 30, 6:50 am, amuro <(E-Mail Removed)> wrote:

>
> > >>>> Hi, I wonder why the following expression is detected as undefined
> > >>>> expression. In my opinion, this is a "defined" expression.

>
> > >>>> x = *(x++, p); *// line 21

>
> > >>>> $ gcc -Wsequence-point test.c
> > >>>> test.1:21: warning: operation on 'x' may be undefined

>
> > >>>> $ splint test.c
> > >>>> test.c:21:6: Expression has undefined behavior (value of left operand
> > >>>> x is modified by right operand *(x++, p)): x = *(x++, p)

>
> > >>>> Another expression looks similar with previous expression shows
> > >>>> expected result by GCC but not Splint. That means GCC does not
> > >>>> consider it as undefined

>
> > >>> it may be that gcc does not *detect* that it is undefined. A compiler
> > >>> is not obliged to diagnose undefined behaviour. A compiler isn't
> > >>> obliged to do *anything* specific with undefined behaviour. After all
> > >>> the behaviour is not defined...

>
> > >> Thank you for reply. You're right that a compiler is not obliged to
> > >> diagnose undefined behaviour.
> > >> I'd like to change my question. Does the expression, "x = *(x++, p);"
> > >> result in undefined behavior in terms of C Specification?

>
> > > Yes. *You cannot modify a variable twice between sequence points,
> > > since there is no order defined. *IOW, "*(x++, p)" may be reasonably
> > > defined, but the time at which the ++ happens relative to the
> > > assignment into x is *not*.

>
> > The comma's introduces a sequence point between the evaluations of x++
> > and p, and the assignment cannot be evaluated until after p is
> > evaluated, so how is the behavior undefined? *AFAICT, that expression
> > must have identical behavior to the well-defined "x++; x = *p;".

>
> I thought the order of eval of comma expressions is not defined. *So
> it could be x = *p; x++; as well.
>
> Tom


[#2] The left operand of a comma operator is evaluated as a
void expression; there is a sequence point after its
evaluation. Then the right operand is evaluated; the result
has its type and value.

-David
 
Reply With Quote
 
Marcin Grzegorczyk
Guest
Posts: n/a
 
      01-03-2011
Keith Thompson wrote:
> amuro<(E-Mail Removed)> writes:
>> I'v cited C draft, Committee draft, Nov 16, 2010 at
>> http://www.open-std.org/jtc1/sc22/wg...docs/n1539.pdf

>

[...]
> There's a newer draft, n1547.pdf, available from the same source.


N1539 and N1547 are supposed to be (and, I believe, are) the same,
except that N1547 has differences to N1516 marked on the margins.

--
Marcin Grzegorczyk
 
Reply With Quote
 
Marcin Grzegorczyk
Guest
Posts: n/a
 
      01-03-2011
Tim Rentsch wrote:
> Seebs<(E-Mail Removed)> writes:
>
>> On 2010-12-30, amuro<(E-Mail Removed)> wrote:
>>> Yes. you're right. Hm.. the reason why I've cited is that it seems to
>>> be more clear than n1256.

>>
>> Well, yes. That's one of the points of the revision. However, in some
>> cases, it will make a thing clear which *isn't true* in the old document.

>
> Except in this case the point made clear _is_ true in the old
> document. And C89 as well.


I'd say the point was ambiguous in C89 and C99.

IIRC, Larry Jones said on comp.std.c something to the effect of "the new
sequencing specification is supposed to say what we always meant the
Standard to say" (sorry if I grossly misquote you, Larry)
--
Marcin Grzegorczyk
 
Reply With Quote
 
Marcin Grzegorczyk
Guest
Posts: n/a
 
      01-04-2011
amuro wrote:
[x = *(x++, p);]
> Hm.. Is the assignment to x sequenced after post-increment of x?
>

[snip quotes of the N1539 draft]
>
> So in the expression "x = *(x++, p)", assignment to x is sequenced
> after the value computation
> of right operand "*(x++, p)". It does not mean assignment to x is
> sequenced after the side effect
> of right operand. But, during value computation, it causes sequence
> point. After all,
> the assignement to x is sequenced after the side effect of post-
> increment of x.
> That means those two side effect actions are not in between two
> sequence points.


Yes, the side effect of the assignment is sequenced after the side
effect of the post-increment (because any side effects of the
sub-expression `x++` are sequenced before the value computation of `p`
(6.5.17p2 and the definition of a sequence point in 5.1.2.3p3), which is
sequenced before the value computation of the indirection operator
(6.5p1), which is sequenced before the side effect of the assignment
(6.5.16p3). That is my reading of N1539, anyway.)

However, the side effects of `x++` are unsequenced relative to the value
computation of the left-hand side of the assignment operator (the lvalue
`x`). And since value computation of an lvalue involves "determining
the identity of the designated object" (5.1.2.3p2), it appears the
behaviour is still undefined (6.5p2).
--
Marcin Grzegorczyk
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      01-04-2011
On Mon, 3 Jan 2011 04:41:29 -0800 (PST), Tom St Denis <(E-Mail Removed)>
wrote:

>On Dec 30 2010, 3:38*am, Stephen Sprunk <(E-Mail Removed)> wrote:
>> On 30 Dec 2010 01:51, (E-Mail Removed) wrote:
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> > On Dec 30, 1:06 am, amuro <(E-Mail Removed)> wrote:
>> >> On 12?30?, ??4?00?, Nick Keighley <(E-Mail Removed)>
>> >> wrote:

>>
>> >>> On Dec 30, 6:50 am, amuro <(E-Mail Removed)> wrote:

>>
>> >>>> Hi, I wonder why the following expression is detected as undefined
>> >>>> expression. In my opinion, this is a "defined" expression.

>>
>> >>>> x = *(x++, p); *// line 21

>>
>> >>>> $ gcc -Wsequence-point test.c
>> >>>> test.1:21: warning: operation on 'x' may be undefined

>>
>> >>>> $ splint test.c
>> >>>> test.c:21:6: Expression has undefined behavior (value of left operand
>> >>>> x is modified by right operand *(x++, p)): x = *(x++, p)

>>
>> >>>> Another expression looks similar with previous expression shows
>> >>>> expected result by GCC but not Splint. That means GCC does not
>> >>>> consider it as undefined

>>
>> >>> it may be that gcc does not *detect* that it is undefined. A compiler
>> >>> is not obliged to diagnose undefined behaviour. A compiler isn't
>> >>> obliged to do *anything* specific with undefined behaviour. After all
>> >>> the behaviour is not defined...

>>
>> >> Thank you for reply. You're right that a compiler is not obliged to
>> >> diagnose undefined behaviour.
>> >> I'd like to change my question. Does the expression, "x = *(x++, p);"
>> >> result in undefined behavior in terms of C Specification?

>>
>> > Yes. *You cannot modify a variable twice between sequence points,
>> > since there is no order defined. *IOW, "*(x++, p)" may be reasonably
>> > defined, but the time at which the ++ happens relative to the
>> > assignment into x is *not*.

>>
>> The comma's introduces a sequence point between the evaluations of x++
>> and p, and the assignment cannot be evaluated until after p is
>> evaluated, so how is the behavior undefined? *AFAICT, that expression
>> must have identical behavior to the well-defined "x++; x = *p;".

>
>I thought the order of eval of comma expressions is not defined. So
>it could be x = *p; x++; as well.


When the comma is used to separate function arguments, the order of
evaluation is unspecified. When the comma operator is used, it
specifies a sequence point which requires the left operand to be
evaluated and all side effects to be completed prior to evaluating the
right operand. Not the only example of a token having multiple
meanings depending on context.

--
Remove del for email
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" Adem C++ 42 11-04-2008 12:39 PM
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" Adem C Programming 45 11-04-2008 12:39 PM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM



Advertisments