🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #4408

Re: On sequence points and evaluation order

#4408
From: Christopher R. Volpe
Date: Fri, 01 Dec 1995 16:47
125 lines
5592 bytes
In article <49m4kf$d6v@natasha.rmii.com>, jcoffin@rmii.com (Jerry Coffin) writes:
>nickie@cs.cornell.edu (Nikolaos Papaspyrou) wrote:

>>Question 1: Consider the following two programs.
>
>>   int i = 0;                     int i = 0;
>
>>   int main () {                  int f () { return (i = 1); }
>>      return (i = 1) + i;
>>   }                              int main () {
>>                                     return f() + i;
>>                                  }
>
>>As far as common sense is concerned, the two programs are equivalent.
>>I believe the behavior of the program on the left is undefined
>>according to the standard, since between two consecutive sequence
>>points (before and after the return statement) a write and a read
>>operation occur for object "i", and the read operation does not intend
>>to calculate the value that the write operation will store.
>
>>The program on the right does exactly the same thing, only there seems
>>to be an extra sequence point just before function "f" is called. Now
>>the read and write operations do not occur between two successive
>>sequence points. Therefore (please correct me in this, for I believe
>>this statement is wrong), the behavior of this program is not
>>undefined (so what is it?).
>
>Both are undefined 

No. The one on the left is undefined. It can crash. The one on the right
returns a value to the OS that must be either 1 or 2. 

>- the order of evaluation of `f() + i' is undefined.

The standard does not associate the word "undefined" with order of evaluation.

>The compiler is free to treat it as if you had written either:
>int temp = i;
>i = temp + f();
>
>or:
>
>f();
>i = i + i;

I think you're confused here. I don't see either of those programs doing
anything remotely like assigning the result of (i+i) back into i.

>
>(Or in theory, since this is undefined behavior, it can do anything else
>it wants to as well, but generally it'll evaluate the arguments and
>produce a result, but you can't predict what it'll be. )

Except that it's not undefined behavior in the program on the right.

>
>>Question 2: Consider the following similar program.
>
>>   int f () { printf("message 1\n"); return 1; }
>>   int g () { printf("message 2\n"); return 2; }
>
>>   int main () {
>>      return f() + g();
>>   }
>
>>Evaluation order is not specified and therefore we cannot determine
>>which message will be printed first. However, behavior is not
>>undefined but depends on the implementation.
>
>>Assuming that both programs in the previous question have undefined
>>behavior (as I believe it is), why do we consider a call to "printf"
>>to be so drastically different from a write operation to a variable?
>
>Because it's a function call, and a sequence point between having
>evaluated the arguments to a function, and actually invoking the
>function.

And if you noticed in the right-hand program in the first question, there was
also a function call and sequence point. 


>>How will we implement "printf" after all? Won't it have to change a
>>few global or static objects, since we usually have buffers for
>>"stdout"?  And if I implement such a buffer myself, in my own "printf"
>>in my own program, will two calls like this have undefined behavior
>>because I'm assigning twice to the same variable?
>
>No - there's always a sequence point betwen evaluating the arguments to
>a function, and invoking the function.  Therefore, printf is not the
>issue here.  The presence or lack of a sequence point is the issue.  If
>you have a function call, it forces a sequence point.  If you used
>various other things, they force sequence points as well. e.g. if you'd
>written:
>
>	f(), i = i + i;
>
>you'd have a perfectly valid, well defined statement.  However, if you
>do the more obvious:
>
>	i = f(), i+i;
>
>I believe the result is still technically undefined.  The assignment

Huh? You first have "i = f()", which is fine, then you have a comma operator,
which forces a sequence point, then you have "i+i", which is evaluated and the
results discarded. Why is this undefined? 

>operator doesn't force a sequence point, so in theory the compiler could
>treat evaluate the i on the left side before or after the entire right
>side.  However, from a practical viewpoint, it's pretty hard to assign
>the correct value to i until after you figure out what it is, which is
>done after the sequence point introduced by the comma operator.  OTOH,

Perhaps you meant "i = (f(), i+i)". This is still not undefined. The
expression on the right is used to compute the new value of i in the top level
assignment. And the subexpression on the right has a sequence pint between the
evaluatin of "i=1" in f(), and the evaluation of "i+i". I see nothing
technically wrong with this according to the rules of the STandard.


--

Chris Volpe				Phone: (518) 387-7766 (Dial Comm 8*833
GE Corporate R&D			Fax:   (518) 387-6560
PO Box 8, Schenectady, NY 12301		Email: volpecr@crd.ge.com
Technical Details
Message-ID: <49nbij$e1c@rdsunx.crd.ge.com>
Path: arc1-ca.pugleaf.net!bart.crd.ge.com!volpe
References: <49l428$od0@bolverk.cs.cornell.edu> <49m4kf$d6v@natasha.rmii.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!bart.crd.ge.com!volpe
From: volpe@bart.crd.ge.com (Christopher R. Volpe)
Newsgroups: comp.std.c
Subject: Re: On sequence points and evaluation order
Date: 1 Dec 1995 16:47:15 GMT
Organization: GE Corporate Research & Development
Sender: volpe@bart (Christopher R. Volpe)
Distribution: world
Message-ID: <49nbij$e1c@rdsunx.crd.ge.com>
References: <49l428$od0@bolverk.cs.cornell.edu> <49m4kf$d6v@natasha.rmii.com>
Reply-To: volpe@ausable.crd.ge.com
NNTP-Posting-Host: bart.crd.ge.com