Re: [C, C++] "(a=b) = c;" Illegal or Undefined?
From: Robert W Hand (rwhand_at_NOSPAMoperamail.com)
Date: 02/01/04
- Next message: Ulrich Eckhardt: "Re: Proper case using std:string"
- Previous message: Dark Alchemist: "Re: Proper case using std:string"
- In reply to: Arthur J. O'Dwyer: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Next in thread: Martijn Lievaart: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: Martijn Lievaart: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: Arthur J. O'Dwyer: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: B. v Ingen Schenau: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 01 Feb 2004 05:21:40 -0500
On Sat, 31 Jan 2004 15:17:56 -0500 (EST), "Arthur J. O'Dwyer"
<ajo@nospam.andrew.cmu.edu> wrote:
> How is it "pretty clear"? Did you have to evaluate the function
>to determine that it was "clear"?
You have a point here. What I am saying is that a compiler might look
at that function during compilation and figure that the function body
has no external effects other than to assign return buf[0]. A
compiler could optimize this function, but it might not be able to
optimize other functions.
In reading of 6.5.16, paragraphs 3 and 4, I am led to think that the
order of evaluation of the left and right operand is unspecified. It
occurs somewhere during the previous and next sequence point. The
side effect of updating the value of the left operand is also between
the previous and next sequence point. Finally the assignment
operation stores the value of the right operand into the object
referenced by the left operand.
Now I agree that there is going to be some order. You need the right
operand value before it is assigned to the left operand object. But
the standard seems to go out of its way to leave as much of the order
unspecified as possible to allow greater latititude to compiler makers
for optimizations.
> How is that any different from your needing the *left* operand address
>before you assign to it? In Example 7, you must call getchar() to
>determine the right-hand side; in your example, you must call f() to
>determine the left-hand side. I don't see how the hypothetical underlying
>"clairvoyant" implementation is any different.
Aren't you going to give me some magical powers? :-) But seriously
and maybe I am reading something into the Standard, but the right hand
side expression provides a value. The left hand side expression
provides an object to store the value in. Let's consider:
int i=0, j = 4;
i=j;
The right operand's value is 4. The left operand's value is 0 before
assignment and 4 after assignment. But what is really important is
the object that i refers to. It receives the assignment. I really do
not need to know the integer value of i for that assignment.
>> > Would you claim that this program
>> >
>> > void foo(int n) { puts("foo"); }
>> > int bar(void) { puts("bar"); return 0; }
>> > int main(void) { foo(bar()); return 0; }
>> >
>> >could print as output "bar/foo" OR "foo/bar"?
>>
>> No, this example is different. It involves function calls rather than
>> assignment. There is a sequence point before the call of the
>> function. So in main, bar() must be evaluated first.
>
> You are correct that the value of bar() must be evaluated before
>foo() can be called -- but weren't you just arguing, right above,
>that it's "pretty clear" that bar() always returns 0, and thus we
>don't have to call it to determine its value? [Possible strawman
>argument -- but I'm still not clear on where you draw the line between
>"absolutely ridiculous" and "pretty clear." ;-) ]
bar() has a side-effect of printing to the standard output. That is
an external effect that cannot be eliminated by the compiler as an
optimization.
Subclause 5.1.2.3 paragraphs 1, 2, 3 are key. The first tells us that
the semantics of the Standard describe an abstract machine without
optimizations. The second defines side-effects and sequence points.
The third tells us that an actual implementation may optimize away
part of an expression if its value is not needed or if no needed
side-effects are produced, including those caused by calling a
function.
I don't believe that I used the term "absolutely ridiculous". I
usually try to avoid such volatile terms in a usegroup as they may
cause anger in the reader. I'm trying to have just a civil
conversation and to learn more about C and C++. I'll own up to
"pretty clear", but that is not volatile, is it? It can get confusing
to follow these threads sometimes. Anyway, I know that I get lost at
times. ;-)
>> > Or that this program
>> >
>> > int main(void)
>> > {
>> > if (printf("Hello\n"))
>> > printf("world\n");
>> > return 0;
>> > }
>> >
>> >would be within its rights to print "world/Hello"?
>>
>> No, again there is a sequence point after the conditional.
>
> Chapter and verse, please.
After the control expression of the if statement, there is a sequence
point. See 6.8/4 of the C Standard. So "Hello" will be printed
before "world" in all conforming implementations.
-- Best wishes, Bob
- Next message: Ulrich Eckhardt: "Re: Proper case using std:string"
- Previous message: Dark Alchemist: "Re: Proper case using std:string"
- In reply to: Arthur J. O'Dwyer: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Next in thread: Martijn Lievaart: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: Martijn Lievaart: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: Arthur J. O'Dwyer: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Reply: B. v Ingen Schenau: "Re: [C, C++] "(a=b) = c;" Illegal or Undefined?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|