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

A

amuro

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

Thx in advance.
 
N

Nick Keighley

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

amuro

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?
 
R

robertwessel2

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

Stephen Sprunk

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

S
 
A

amuro

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

Hm.. Is the assignment to x sequenced after post-increment of x?

By "6.5.16p3 Assignment operators", "The side effect of updating the
stored value of
the left operand is sequenced after the value computations of the left
and right operands."

Evaluation consists of value computation and initiation of side
effect. Value computation
can be cosidered as evaluation except applying side effect. (5.1.2.3p2
Program execution)

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

amuro

Hm.. Is the assignment to x sequenced after post-increment of x?

By "6.5.16p3 Assignment operators", "The side effect of updating the
stored value of
the left operand is sequenced after the value computations of the left
and right operands."

Evaluation consists of value computation and initiation of side
effect. Value computation
can be cosidered as evaluation except applying side effect. (5.1.2.3p2
Program execution)

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.

I'v cited C draft, Committee draft, Nov 16, 2010 at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1539.pdf
 
I

Ike Naar

[ about x = *(x++, p); ]
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;".

You are probably thinking of the (acceptable) sequence of evaluations:

x++ , p , * , lhs x , =

But the evaluation of the lefthandside of the assigment (``lhs x'')
can happen before ``x++'' on the righthandside is evaluated, so
this is also an accecptable sequence of evaluations:

lhs x , x++ , p , * , =

with behaviour identical to the well-defined ``x = *p; x++;'' .
 
E

Eric Sosman

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.

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

amuro

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

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

[about x = *(x++, p);]

I think it can be derived that there exists sequence point between
`x=`(assignment) and side effect generated by 'x++' with respect to
all the possible(acceptable) evaluation sequences.

* "a > b" means that b is sequenced before a

'x=' > value computation of LHS and RHS of x= which requires
"evaluating p" // by 6.5.16p3
"evaluating p" > side effect by x+
+ // by comma op

Therefore.. 'x=' is sequenced before side effect of x++.
IOW, there's a sequence point between 'x=' and 'x++'..
 
E

Eric Sosman

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

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

[about x = *(x++, p);]

I think it can be derived that there exists sequence point between
`x=`(assignment) and side effect generated by 'x++' with respect to
all the possible(acceptable) evaluation sequences.

* "a> b" means that b is sequenced before a

'x='> value computation of LHS and RHS of x= which requires
"evaluating p" // by 6.5.16p3
"evaluating p"> side effect by x+
+ // by comma op

Therefore.. 'x=' is sequenced before side effect of x++.
IOW, there's a sequence point between 'x=' and 'x++'..

"A must be evaluated before B" does not imply that "there is
a sequence point between A and B." Yes, "before" and "sequence"
sound as if they refer to the same notion of order, but keep in
mind that the Standard is a technical document and uses language
in a technical sense. "Sequence point," in the Standard, means
exactly and only what its definition (5.1.2.3p2) says -- and what
the definition says is that an SP is a *specified* point, that is,
there's an SP where the Standard *specifies* one, period. Those
specifications are scattered throughout the Standard (and summarized
in Annex C), and those are the *only* SP specifications.

The reason (or *a* reason) for all this hair-splitting is that
the Standard tries to describe the meaning of a C program without
reference to the implementation. By divorcing the notion of SP from
the notion of "order of operation," the Standard can talk about the
meaning without hobbling the compiler and inhibiting optimizations.
 
S

Stephen Sprunk

[ about x = *(x++, p); ]
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;".

You are probably thinking of the (acceptable) sequence of evaluations:

x++ , p , * , lhs x , =

But the evaluation of the lefthandside of the assigment (``lhs x'')
can happen before ``x++'' on the righthandside is evaluated, so
this is also an accecptable sequence of evaluations:

lhs x , x++ , p , * , =

with behaviour identical to the well-defined ``x = *p; x++;'' .

Ah; that explains it. Thanks.

S
 
K

Keith Thompson

amuro said:
I'v cited C draft, Committee draft, Nov 16, 2010 at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1539.pdf

Yes, I thought you were quoting a C201X draft; C99 doesn't use the
"sequenced after" wording.

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

But the C201X documents are drafts of the new standard, not of the
current C99 standard. There are no compilers that conform to C201X,
since it doesn't exist yet. (Finding conforming C99 compilers is hard
enough.)

C201X changes the description of sequence points. IMHO the new wording
is clearer, and I think it's intended to describe the same underlying
semantics. But if you want a document that describes the language as
it's currently defined, you'll want n1256.pdf.
 
A

amuro

[about x = *(x++, p);]
I think it can be derived that there exists sequence point between
`x=`(assignment) and side effect generated by 'x++' with respect to
all the possible(acceptable)  evaluation sequences.
* "a>  b" means that b is sequenced before a
'x='>  value computation of LHS and RHS of x= which requires
"evaluating p"  // by 6.5.16p3
"evaluating p">  side effect by x+
+                                          // by comma op
Therefore.. 'x=' is sequenced before side effect of x++.
IOW, there's a sequence point between 'x=' and 'x++'..

     "A must be evaluated before B" does not imply that "there is
a sequence point between A and B."  Yes, "before" and "sequence"
sound as if they refer to the same notion of order, but keep in
mind that the Standard is a technical document and uses language
in a technical sense.  "Sequence point," in the Standard, means
exactly and only what its definition (5.1.2.3p2) says -- and what
the definition says is that an SP is a *specified* point, that is,
there's an SP where the Standard *specifies* one, period.  Those
specifications are scattered throughout the Standard (and summarized
in Annex C), and those are the *only* SP specifications.

Thank you for pointing out my misled statement. As you mentioned,
"A must be evaluated before B" does not imply that "there is
a sequence point between A and B.".
Precisely, the following would be my intention.
(1) A is sequenced after B *AND* (2) there exists a SP between A and
B.
Those two conditions seem to meet escaping from the undefinedness.

Does the presence of partial ordering such as "sequenced before/
after"
may give the restricted position of SP in evaluation sequences?

e.g) A -> .... -> SP -> .. -> B

comma operator gives the partial order of both operands *AND*
SP between both operands. (b)

'x=' > evaluating p // --- (a)
evaluating p > SP > 'x++' // --- (b)
By those two constraints (a),(b), all possible evaluation sequences
should be like the following.

'x++' -> incrementing x -> .. SP -> p-> 'x='

The difference between your statement and mine seems to be the
interpretation of effect of SP. I've extended(?) the effect of SP
in terms of whole evaluation sequences. So SP splits the whole
evaluation sequence by previous and next from the position of SP.
Not just point between both operands for example comma operator.
 
A

amuro

Yes, I thought you were quoting a C201X draft; C99 doesn't use the
"sequenced after" wording.

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

But the C201X documents are drafts of the new standard, not of the
current C99 standard.  There are no compilers that conform to C201X,
since it doesn't exist yet.  (Finding conforming C99 compilers is hard
enough.)

C201X changes the description of sequence points.  IMHO the new wording
is clearer, and I think it's intended to describe the same underlying
semantics.  But if you want a document that describes the language as
it's currently defined, you'll want n1256.pdf.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Thank you! I would check n1547.pdf.
 
A

amuro

And that means your argument will suddenly become relevant when you
have a C1X compiler. :)

I think that's an improvement to the language, but right now it's
not there.

-s
Yes. you're right. Hm.. the reason why I've cited is that it seems to
be more clear than n1256.
Thanks.
 
S

Seebs

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.

-s
 
T

Tim Rentsch

Ike Naar said:
[ about x = *(x++, p); ]
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;".

You are probably thinking of the (acceptable) sequence of evaluations:

x++ , p , * , lhs x , =

But the evaluation of the lefthandside of the assigment (``lhs x'')
can happen before ``x++'' on the righthandside is evaluated, so
this is also an accecptable sequence of evaluations:

lhs x , x++ , p , * , =

This statement is correct.
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'.
 
T

Tim Rentsch

Seebs said:
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.
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top