Topic: i=i++ ? order of evaluation


Author: jimad@microsoft.com (Jim Adcock)
Date: Wed, 17 Nov 1993 18:40:40 GMT
Raw View
In article <rfgCGJ13K.n01@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
|P.S.  I am constantly amazed at the number of outstanding problems in the
|current X3J16 working papers for which well-wordsmith'd solutions are
|already readily available in the ANSI/ISO C standard...

Agreed.  Again, note that the ARM is only one of *two* base documents
for the ANSI/ISO C++ standardization efforts.  People who *only*
have the ARM don't know the half of it.  The ANSI/ISO C Standard is
the other half.  Fortunately, Osborne has recently published an
"Annotated" version of the ANSI/ISO C Standard, so that people can
now find *both* at better computer book stores.





Author: jimad@microsoft.com (Jim Adcock)
Date: Thu, 4 Nov 1993 20:01:47 GMT
Raw View
In article <AConxri8t2@cer.nsk.su> gtm@cer.nsk.su writes:
|Consider the expression in context of global `int i=0;' definition:
|
|i=i++;   // (1)
|
|ARM says (p.46) that "Except where noted order of evaluation of operands
|of individual operators is undefined".

These issues were well-covered in the ANSI/ISO C Standard, where there
was a clear model of execution, with sequence points etc.  That standard
says that accessing any variable more than once for modification between
two adjecent sequence points is undefined.  In the above expression
i is accessed twice for modification, and thus is undefined.

The C++ Standardization effort has not yet addressed these issues, to my
knowledge.  My only hope is that they don't neglect to address these
issues, nor that they do worse than ANSI/ISO C.  I'd prefer that they
adopt much of the language of the C Standard re sequence points, constraints,
etc wholesale.  However, if they 'just' continue to follow the ARM document
format, this may not happen.





Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 15 Nov 1993 09:30:56 GMT
Raw View
In article <1993Nov4.203442.19953@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>In article <CFxEHD.2I6@crdnns.crd.ge.com>, volpe@bart.crd.ge.com (Christopher R. Volpe) writes:
>
>> It's all a matter of sequence points. The ARM doesn't discuss them, but I
>> suspect (and hope) the ANSI C++ standard will adopt the same rules as
>> ANSI C.
>
>I hope the C++ standard adopts those rules as a minimum, and that it will
>go beyond them.
>
>    int x;
>    (x = 0) + (x = -1);
>
>I have been told that a standard-conforming C compiler will leave x
>with the value 0 or -1.  But I can imagine an implementation in which
>the two side effects are intermingled, neither occurring entirely before
>the other.  Then the resultant value of x would not be so predictable.
>I would like the C++ standard to say explicitly whether such intermingling
>may occur.

As is so often the case, if the X3J16 committee would just pay more attention
to the well-tuned wording already present in the C standard, this issue could
have been resolved already.

ANSI C standard, section 3.3:

 "Between the previous and next sequence point an object shall have
 it stored value modified at most once by the evaluation of an ex-
 pression."

(This rule is not in a constraints or a syntax section, so violations of
this rule result in TOTALLY undefined behavior... at least in ANSI C...
and if similar language were present in the C++ standard, I think that
perhaps would satisfy Scott Turner's desire.)

P.S.  I am constantly amazed at the number of outstanding problems in the
current X3J16 working papers for which well-wordsmith'd solutions are
already readily available in the ANSI/ISO C standard... and I am likewise
constantly amazed at X3J16's apparent determination to reinvent the wheel
(from scratch of course) with respect to so many of these things.  I am
however greatly consoled by the knowledge that they will eventually just
run out of time, and that they will then have no other choice than to
simply adopt big hunks of the ANSI/ISO C standard verbatim (which is
something I think they should have done long long ago).

--

-- Ronald F. Guilmette, Sunnyvale, California -------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: volpe@bart.crd.ge.com (Christopher R. Volpe)
Date: Wed, 3 Nov 1993 17:12:49 GMT
Raw View
In article <AConxri8t2@cer.nsk.su>, Alexander Gootman <gtm@cer.nsk.su> writes:
>Consider the expression in context of global `int i=0;' definition:
>
>i=i++;   // (1)

Since "i" is just an int, this statement is the same in C++ as at is in C,
which is undefined, since the object is modified twice between sequence
points.

>
>ARM says (p.46) that "Except where noted order of evaluation of operands
>of individual operators is undefined".
>So, arguments of op=, `i' and `i++' are evaluated and give l-value `i'
>and int zero correspondingly. BUT the result of (1)
>should be well defined if the op= is evaluated LATER then its operands.

You have to draw a distinction between when the operators in question are
evaluated (to compute the value they yield), and when their side effects
take place. Yes, the evaluation of op= takes place after that of
its operand, op++. But the side effect of op++ could occur after that
of op=.

>To formulate the question: the example (ARM, p46) `i=v[i++]' does not
>illustrate the statement of mainstream text, is it correct?

The examples seem to suggest that the rules are the same as for ANSI C,
But they are pretty sloppy about trying to express this. The example
"i=v[i++]" really has nothing to do with order of evaluation of operands.
The only operator that has more than one operand here is op=, and the order
in which its two operands are evaluated has no effect on the situation.
It's all a matter of sequence points. The ARM doesn't discuss them, but I
suspect (and hope) the ANSI C++ standard will adopt the same rules as
ANSI C.

>Cfront and Zortech evaluate (1) to 0 but Boralnd gives 1 .
>   I would like Borland be wrong: use to teach students that operator
>is just another syntax for a function call (am I right? :-( ), and
>according to K&R book on ANSI C a function is invoked after evaluating
>arguments. Btw `i=i++' could be sensible through inlining.

An operator in C (and I hope this is true for C++ except in cases where
operators are explicitly overloaded) is not the same as a function call. In
a function call, there is a sequence point after the evaluation of all the
function arguments and immediately before the actual transfer of control.
However, with an operator, there is no sequence point between the evaluation
of the operands and the actual invocation of the operator.

>
>   Comments, please.
>
>Alexander A. Gootman     Novosibirsk, Russia
>

--

Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com




Author: pkt@lpi.liant.com (Scott Turner)
Date: Thu, 4 Nov 1993 20:34:42 GMT
Raw View
In article <CFxEHD.2I6@crdnns.crd.ge.com>, volpe@bart.crd.ge.com (Christopher R. Volpe) writes:

> It's all a matter of sequence points. The ARM doesn't discuss them, but I
> suspect (and hope) the ANSI C++ standard will adopt the same rules as
> ANSI C.

I hope the C++ standard adopts those rules as a minimum, and that it will
go beyond them.

    int x;
    (x = 0) + (x = -1);

I have been told that a standard-conforming C compiler will leave x
with the value 0 or -1.  But I can imagine an implementation in which
the two side effects are intermingled, neither occurring entirely before
the other.  Then the resultant value of x would not be so predictable.
I would like the C++ standard to say explicitly whether such intermingling
may occur.

    x = -x;

Second, the above assignment contains one side effect.  It also contains a
fetch of the value of x.  I would like the C++ standard to say that the
fetch takes place before the side effect.

Maybe the standard doesn't need to address these issues because they're
obvious to everyone but me.  In any case, getting sequence points into
the C++ standard may be easier, and is more of a priority.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: volpe@bart.crd.ge.com (Christopher R. Volpe)
Date: Thu, 4 Nov 1993 22:11:18 GMT
Raw View
In article <1993Nov4.203442.19953@lpi.liant.com>, pkt@lpi.liant.com (Scott Turner) writes:
>In article <CFxEHD.2I6@crdnns.crd.ge.com>, volpe@bart.crd.ge.com (Christopher R. Volpe) writes:
>
>> It's all a matter of sequence points. The ARM doesn't discuss them, but I
>> suspect (and hope) the ANSI C++ standard will adopt the same rules as
>> ANSI C.
>
>I hope the C++ standard adopts those rules as a minimum, and that it will
>go beyond them.

Beyond in what way? Do you want more sequence points defined?

>
>    int x;
>    (x = 0) + (x = -1);
>
>I have been told that a standard-conforming C compiler will leave x
>with the value 0 or -1.  But I can imagine an implementation in which

You've been told wrong. The above can leave your age in days as the value of
x. The behavior is undefined.

>the two side effects are intermingled, neither occurring entirely before
>the other.  Then the resultant value of x would not be so predictable.
>I would like the C++ standard to say explicitly whether such intermingling
>may occur.

It will, if it includes everything from the C standard relating to this.

>
>    x = -x;
>
>Second, the above assignment contains one side effect.  It also contains a
>fetch of the value of x.  I would like the C++ standard to say that the
>fetch takes place before the side effect.

The C standard guarantees that the above expression is well-defined.

So, in what way do you want the rules for C++ to go beyond those of C?

--

Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com




Author: Alexander Gootman <gtm@cer.nsk.su>
Date: Wed, 03 Nov 93 17:13:06 +0300
Raw View
Consider the expression in context of global `int i=0;' definition:

i=i++;   // (1)

ARM says (p.46) that "Except where noted order of evaluation of operands
of individual operators is undefined".
So, arguments of op=, `i' and `i++' are evaluated and give l-value `i'
and int zero correspondingly. BUT the result of (1)
should be well defined if the op= is evaluated LATER then its operands.
To formulate the question: the example (ARM, p46) `i=v[i++]' does not
illustrate the statement of mainstream text, is it correct?
Cfront and Zortech evaluate (1) to 0 but Boralnd gives 1 .
   I would like Borland be wrong: use to teach students that operator
is just another syntax for a function call (am I right? :-( ), and
according to K&R book on ANSI C a function is invoked after evaluating
arguments. Btw `i=i++' could be sensible through inlining.

   Comments, please.

Alexander A. Gootman     Novosibirsk, Russia