Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

postfix operator++

152 views
Skip to first unread message

ravinder thakur

unread,
May 17, 2012, 3:13:35 AM5/17/12
to
{ Though this question may seem trivial, it may also be confusing and
tricky in light of the series of relevant changes in the standard,
so hopefully the follow-ups will clear up the issue. -mod }

hello guys,

I am kind of puzzled by one simple c++ constuct. What should be the
value of x after the statement:

int x = 10;
x = x++;

I expect value of x to be 10 after the second assignment, however its
coming out to be 11. Any ideas whats happening ?

Thanks!
xoxo


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Radu

unread,
May 17, 2012, 9:43:56 AM5/17/12
to
On May 17, 10:13 am, ravinder thakur <ravindertha...@gmail.com> wrote:
> { Though this question may seem trivial, it may also be confusing and
> tricky in light of the series of relevant changes in the standard,
> so hopefully the follow-ups will clear up the issue. -mod }
>
> hello guys,
>
> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?
>
> Thanks!
> xoxo
>

Actually you are forgetting the order in which operations are carried
out:
1. Evaluate and compute all the operations declared on the right side.
2. Assign the resulted value to the variable.

Now regarding step 1: ++ is the increment operator. The fact that is
after x (it's postfix) only means that it will be evaluated later
rather than sooner, but it will get evaluated before the result is
assigned (that would be step 2).

Hope it helps.

PiotrN

unread,
May 17, 2012, 9:44:21 AM5/17/12
to
On 17 Maj, 09:13, ravinder thakur <ravindertha...@gmail.com> wrote:
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?
>

I believe this is equivalent to:

int x = 10;
x = x, ++x;

So it is obvious, x is 11 after all.

Consider this:
int x = 10;
int a;
a = x++;

a is 10 and x is 11
same as for this code:
a = x, ++x;

HTH,
Piotr

Francis Glassborow

unread,
May 17, 2012, 9:44:50 AM5/17/12
to
On 17/05/2012 08:13, ravinder thakur wrote:
> { Though this question may seem trivial, it may also be confusing and
> tricky in light of the series of relevant changes in the standard,
> so hopefully the follow-ups will clear up the issue. -mod }
>
> hello guys,
>
> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?
>
> Thanks!
> xoxo
>

You have invoked undefined behaviour because your assignment statement
modifies x twice without an intervening sequence point. This is always a
no no in C and C++ for built-in types. The same rule applies to
struct/class types except that in most instances where it looks as this
has been done (2 modifications to same memory between sequence points)
there are some hidden sequence points because overloaded operators are
actually function calls.

In a sense you are fortunate in that the undefined behaviour has
manifested itself in such a mild fashion whilst alerting you to a
problem in your understanding of C++

Francis

Martin Bonner

unread,
May 17, 2012, 9:45:35 AM5/17/12
to
On Thursday, 17 May 2012 08:13:35 UTC+1, ravinder thakur wrote:
> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?

I'm pretty sure this is undefined behaviour. x is modified twice in the
full expression (once by the post increment, once by the assignment). There
are no intervening sequence points.

The standard allows the program to do anything. (x=10, x=11, x=-42, cause
an access violation, format your hard drive).

muteki

unread,
May 17, 2012, 9:45:50 AM5/17/12
to
On May 17, 12:13 am, ravinder thakur <ravindertha...@gmail.com> wrote:
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?

The final value of x is ambiguous. Please take a look at the link
below.

http://en.wikipedia.org/wiki/Sequence_point

--Chris

Johannes Schaub

unread,
May 17, 2012, 2:34:33 PM5/17/12
to
Am 17.05.2012 09:13, schrieb ravinder thakur:

> hello guys,
>
> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however
> its coming out to be 11. Any ideas whats happening ?
>

In an expression "a = b", if "b" is a value (like "one" or "two"), we
will just take that value and write it into what "a" computed to. If
"b" just refers to an object, we will first have to read a value from
that object, and then write that value into what "a" computed to. The
write into "a" happens *after* the computation of the result of the
expressions "a" and "b" and *before* the computation of the result of
the entire expression "a = b". (The result computation (which is
formally called "value computation" in the Standard) can be an lvalue
refering to an object or a prvalue that is just a value that is not
associated with any object).

Your code snippet has undefined behavior once you run this. The
intuitive reason for this is that there is no "dependency" on the
result of the expression "x++" and the variable "x". Expression "x++"
is the value "x" has before "x" is incremented, and "x++" increments
"x".

So the "x = x++", which assigns to "x" the value of what appears on
the right has no order with respect to the increment that "x++" does -
only with respect to the computation of the value of expression
"x++". The increment and the assign to and of "x" may happen
"overlapping". "x" may end up with a value of 42 or your compiler
could crash with "undefined behavior detected" at runtime - this is
entirely depending on your implementation.

A comparison with a similar construct: If you change "x++" to "++x",
the behavior becomes defined in C++11:

int x = 10;
x = ++x;

Now there is an intuitive "dependency" on the result of "++x" and the
variable "x": The expression "++x" is an lvalue and results in
referring to the variable "x". "++x" is defined as

x = x + 1

So the entire thing becomes

x = (x = x + 1)

Taking the above rules for "a = b", we notice that the left
assignment-write happens after result computation of the right
expression. But the result computation of that right expression
happens in turn after its assignment-write. And that in turn happens
after the result computation of "x + 1". In this code snippet, we have
no overlapping writes (in Standardese, "overlapping writes" will be
two side effects that are neither "indeterminately sequenced" nor will
one be "sequenced before" the other).

This change was a deliberate change in C++11; it was the result of
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637 .

(Note that the Standards use of "value computation" does not refer to
computing a "value". The term "value computation" refers to computing
either an lvalue, prvalue or xvalue. A "value" is what meaning is
contained by the bits in an object, while a lvalue, prvalue or xvalue
is an expression's result when analyzed. The Standard also has the
more precise notions of "lvalue computation" for determining what an
lvalue identifies and "prvalue computation" for what the actual value
of an expression is).

Alf P. Steinbach

unread,
May 17, 2012, 2:45:00 PM5/17/12
to
On 17.05.2012 09:13, ravinder thakur wrote:
> { Though this question may seem trivial, it may also be confusing
> and tricky in light of the series of relevant changes in the
> standard, so hopefully the follow-ups will clear up the
> issue. -mod }

Right.

> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however
> its coming out to be 11. Any ideas whats happening ?

As already noted umpteen times, it's Undefined Behavior.

But why?

Well, in C++03 modifying a value twice between sequence points, such
as within a full-expression, was Undefined Behavior.

However, in C++11 the sequence point idea was ditched in favor of
"sequenced before" and "sequenced after":

C++11 §1.9/13
<quote>
/Sequenced before/ is an asymmetric, transitive, pair-wise relation
between evaluations executed by a single thread (1.10), which induces
a partial order among those evaluations. Given any two evaluations /A/
and /B/, if /A/ is sequenced before /B/, then the execution of /A/
shall precede the execution of /B/. If /A/ is not sequenced before /B/
and /B/ is not sequenced before /A/, then /A/ and /B/ are
/unsequenced/.
[/Note:/ The execution of unsequenced evaluations can overlap. —/end
note/] Evaluations /A/ and /B/ are /indeterminately sequenced/ when
either /A/ is sequenced before /B/ or /B/ is sequenced before /A/, but
it is unspecified which. [/Note:/ Indeterminately sequenced
evaluations cannot overlap, but either could be executed first. —/end
note/]
</quote>

Sometimes computations of values can be sequenced, while side effects
such as updating a variable can be unsequenced:

C++11 §1.9/12
<quote>
/Evaluation/ of an expression (or a sub-expression) in general
includes both value computations (including determining the identity
of an object for glvalue evaluation and fetching a value previously
assigned to an object for prvalue evaluation) and initiation of side
effects.
</quote>

Then finally in §1.9/15 comes the C++11 equivalent of the old
"modified twice" rule:

C++11 §1.9/15:
<quote>
If a side effect on a scalar object is unsequenced relative to either
another side effect on the same scalar object or a value computation
using the value of the same scalar object, the behavior is undefined.
</quote>

So all that's necessary to demonstrate the UB for your case in C++11,
is to check out the sequencing of the built-in assignment operator:

C++11 §5.17/1
<quote>
In all cases, the assignment is sequenced after the value computation
of the right and left operands, and before the value computation of
the assignment expression.
</quote>

The significant wording here is that which does not appear, namely
about sequencing of side effects, such as updates of the variable x in

x = x++;

The side effects are not sequenced. Hence §1.9/15 kicks in, and you
have UB.


Cheers & hth.,

- Alf

ravinder thakur

unread,
May 17, 2012, 2:49:56 PM5/17/12
to
On May 17, 6:44 am, PiotrN <piotr...@gmail.com> wrote:
> On 17 Maj, 09:13, ravinder thakur <ravindertha...@gmail.com> wrote:
>
> > int x = 10;
> > x = x++;
>
> > I expect value of x to be 10 after the second assignment, however
> > its coming out to be 11. Any ideas whats happening ?
>
> I believe this is equivalent to:
>
> int x = 10;
> x = x, ++x;
>
> So it is obvious, x is 11 after all.
>
> Consider this:
> int x = 10;
> int a;
> a = x++;
>
> a is 10 and x is 11
> same as for this code:
> a = x, ++x;

{ Quoted closing greeting and banner removed -mod }

hello Pitor,

I actually did something similar and got surprising results.
int x,y;
x = 10;
x = y = x++;
the value of x is 11 and y is 10.

Go figure :)

James K. Lowden

unread,
May 17, 2012, 4:10:18 PM5/17/12
to
On Thu, 17 May 2012 00:13:35 -0700 (PDT)
ravinder thakur <ravinde...@gmail.com> wrote:

> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment

Ask yourself this: Why do you think x should be 10?

If you want your expectation to match what the machine does, you cannot
use intuition. Be the compiler. Think like a machine.

> x = x++;

Consider the steps:

A. assign x to itself
B. increment x

Even if you don't know which order they'll occur in, neither one ends
with x equal to 10.

Others explained why the statement is invalid, how the details of the
definition of C++ leave it undefined. Valuable as that information is,
it requires you first *analyze* the synxtax: break it down to its
smallest parts.

Having done your best to analyze it, whether or not you get the order
(or parts) right, you at least have something that can be checked, by
asking someone and/or by reading the standard. Each time you do that
you learn something. Do it 10,000 times and, voila, you're an expert.

Namaskaram,

--jkl

Francis Glassborow

unread,
May 17, 2012, 4:16:45 PM5/17/12
to
On 17/05/2012 14:44, PiotrN wrote:
> On 17 Maj, 09:13, ravinder thakur<ravindertha...@gmail.com> wrote:
>> int x = 10;
>> x = x++;
>>
>> I expect value of x to be 10 after the second assignment, however
>> its coming out to be 11. Any ideas whats happening ?
>>
>
> I believe this is equivalent to:
>
> int x = 10;
> x = x, ++x;
>
> So it is obvious, x is 11 after all.
>
> Consider this:
> int x = 10;
> int a;
> a = x++;
>
> a is 10 and x is 11
> same as for this code:
> a = x, ++x;
>
> HTH,
> Piotr
>
>

Please note that the explanations people are giving for the result are
spurious because the Standard makes no requirements for the
consequences of writing twice to the same storage without an
intervening sequence point. It is true that almost always executing
that statement will result in either x being 10 or x being 11 but it
could result in anything including shutting down your computer.

Francis

Ike Naar

unread,
May 17, 2012, 9:04:49 PM5/17/12
to
On 2012-05-17, ravinder thakur <ravinde...@gmail.com> wrote:
> I am kind of puzzled by one simple c++ constuct. What should be the
> value of x after the statement:
>
> int x = 10;
> x = x++;
>
> I expect value of x to be 10 after the second assignment, however its
> coming out to be 11. Any ideas whats happening ?

(Nit: there is no second assignment. The first line is not an assignment).

The value of x equals 10 before the assignment.
If you want x to equal 10 after the assignment as well,
then you actually want the assignment not to change x.
So get rid of the assignment. Problem solved.

Wil Evers

unread,
May 17, 2012, 9:04:20 PM5/17/12
to
James K. Lowden wrote:

> On Thu, 17 May 2012 00:13:35 -0700 (PDT)
> ravinder thakur <ravinde...@gmail.com> wrote:
>
>> int x = 10;
>> x = x++;
>>
>> I expect value of x to be 10 after the second assignment
>
> Ask yourself this: Why do you think x should be 10?
>
> If you want your expectation to match what the machine does, you
> cannot use intuition. Be the compiler. Think like a machine.
>
>> x = x++;
>
> Consider the steps:
>
> A. assign x to itself
> B. increment x
>
> Even if you don't know which order they'll occur in, neither one ends
> with x equal to 10.

Think like a machine? OK, I'll try. What I see is an assignment
statement. Such a statement has a left hand side ('x' here) and a
right hand side ('x++'). So here I go:

(1) evaluate the left hand side. The result is an lvalue referring to
the variable x.

(2) evaluate the right hand side. The result is an rvalue reflecting
the old value of x (10). As a side effect, x is incremented.

(3) Assign the result of (2) to the result of (1). Voila: x
becomes 10.

I would love a language rule that says that (1) must occur before (2),
but in this case, that wouldn't matter. Here, what matters is a rule
that says that (3) will occur after both (1) and (2) have completed.
In any case, the machine will do what the compiler tells it to do.

I know C++ currently does not have such rules, but that doesn't mean
they wouldn't be useful. Until it does, questions like this one will
keep popping up.

- Wil

PiotrN

unread,
May 18, 2012, 9:05:17 AM5/18/12
to
On 17 Maj, 20:49, ravinder thakur <ravindertha...@gmail.com> wrote:
> On May 17, 6:44 am, PiotrN <piotr...@gmail.com> wrote:
>
> > On 17 Maj, 09:13, ravinder thakur <ravindertha...@gmail.com> wrote:
>
> > > int x = 10;
> > > x = x++;
>
> > > I expect value of x to be 10 after the second assignment, however
> > > its coming out to be 11. Any ideas whats happening ?
>
> > I believe this is equivalent to:
>
> > int x = 10;
> > x = x, ++x;
>
> > So it is obvious, x is 11 after all.
>
> > a is 10 and x is 11
> > same as for this code:
> > a = x, ++x;
>
> { Quoted closing greeting and banner removed -mod }
>
> hello Pitor,
>
> I actually did something similar and got surprising results.
> int x,y;
> x = 10;
> x = y = x++;
> the value of x is 11 and y is 10.
>
> Go figure :)

According to my theory:

(x = (y = x)), (++x);
OR without brackets:
y = x, x = y, ++x;
OR in pseudo assembly code:
load r1, x // read from memory x to register r1
store r1, y // store r1 in memory y
load r1, y // not really necessary
store r1, x
load r1, x
inc r1
store r1, x

So, results do not surprise me.

I know that most people (and perhaps C++ standard) say that this is
undefined behavior. But I'd prefer to believe that this is the way the
most compiler interpret such things.

HTH,
Piotr

Francis Glassborow

unread,
May 18, 2012, 9:07:11 AM5/18/12
to
On 18/05/2012 02:04, Ike Naar wrote:
> On 2012-05-17, ravinder thakur<ravinde...@gmail.com> wrote:
>> I am kind of puzzled by one simple c++ constuct. What should be the
>> value of x after the statement:
>>
>> int x = 10;
>> x = x++;
>>
>> I expect value of x to be 10 after the second assignment, however its
>> coming out to be 11. Any ideas whats happening ?
>
> (Nit: there is no second assignment. The first line is not an
assignment).
>
> The value of x equals 10 before the assignment.
> If you want x to equal 10 after the assignment as well,
> then you actually want the assignment not to change x.
> So get rid of the assignment. Problem solved.
>
>

Not so:

void foo(int & i, int & j){
i=j++;
}

int main(){
int i{10};
foo(i, i);
// problem occurs
}


We cannot simply avoid problem code unless we understand why it is a
problem. And note that any reasonable compiler is going to inline foo()
resulting in EXACTLY the original code.

Francis

Martin Bonner

unread,
May 18, 2012, 4:41:02 PM5/18/12
to
On Friday, 18 May 2012 14:05:17 UTC+1, PiotrN wrote:
> I know that most people (and perhaps C++ standard) say that this is
> undefined behavior. But I'd prefer to believe that this is the way
> the most compiler interpret such things.

Sorry. Compilers do all SORTS of things trying to wring a little
extra speed out of your code. If you invoke undefined behaviour like
this, you will get bitten by it eventually.

Anand Hariharan

unread,
May 18, 2012, 5:11:31 PM5/18/12
to
On May 17, 1:34 pm, Johannes Schaub <schaub.johan...@googlemail.com>
wrote:
> A comparison with a similar construct: If you change "x++" to "++x",
> the behavior becomes defined in C++11:
>
> int x = 10;
> x = ++x;
>
> Now there is an intuitive "dependency" on the result of "++x" and the
> variable "x":

Even when restricting this to the "intuitive" level, there is still a
sequencing issue that the instruction to store the incremented value
of x in x and the instruction to store the result of assignment in x
have no relative ordering.

> The expression "++x" is an lvalue and results in
> referring to the variable "x". "++x" is defined as
>
> x = x + 1
>
> So the entire thing becomes
>
> x = (x = x + 1)
>
> Taking the above rules for "a = b", we notice that the left
> assignment-write happens after result computation of the right
> expression. But the result computation of that right expression
> happens in turn after its assignment-write. And that in turn happens
> after the result computation of "x + 1". In this code snippet, we have
> no overlapping writes (in Standardese, "overlapping writes" will be
> two side effects that are neither "indeterminately sequenced" nor will
> one be "sequenced before" the other).
>
> This change was a deliberate change in C++11; it was the result of
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637.
>
> (Note that the Standards use of "value computation" does not refer to
> computing a "value". The term "value computation" refers to computing
> either an lvalue, prvalue or xvalue. A "value" is what meaning is
> contained by the bits in an object, while a lvalue, prvalue or xvalue
> is an expression's result when analyzed. The Standard also has the
> more precise notions of "lvalue computation" for determining what an
> lvalue identifies and "prvalue computation" for what the actual value
> of an expression is).
>

I would appreciate a reference (or a pointer or ... -- pun intended,
of course) to a writeup about what the new C++ language standard has
changed regarding sequence points -- that is (1) targeted to an
audience of ordinary mortals and (2) authored by someone who is
considered authoritative on the subject (*).

thank you,
- Anand

(*) No, Johannes -- I am NOT implying you are not knowledgeable. What
I mean is, I don't want URLs to some discussion form in some web forum
just because a bunch of people clicked the "Like" or "+1" button.

Ike Naar

unread,
May 18, 2012, 5:19:27 PM5/18/12
to
No, the same argument applies to your example.

OP had the following code:

int i{10};
i = i++; // questionable action, intended to establish i == 10
// desired postcondition: i == 10

my advice was to get rid of the second line, because

int i(10);
// desired postcondition: i == 10

does the same thing.

You have the following code:

int i(10);
foo(i, i); // another questionable action, intended to establish i
== 10
// desired postcondition: i == 10

and, again, my advice is to get rid of the second line, because

int i(10);
// desired postcondition: i == 10

does the same thing.

Pete Becker

unread,
May 18, 2012, 8:22:17 PM5/18/12
to
On 2012-05-18 21:11:31 +0000, Anand Hariharan said:

>
> I would appreciate a reference (or a pointer or ... -- pun intended,
> of course) to a writeup about what the new C++ language standard has
> changed regarding sequence points -- that is (1) targeted to an
> audience of ordinary mortals and (2) authored by someone who is
> considered authoritative on the subject (*).
>

The intention was to change terminology but not affect the semantics of
a single-threaded program. The new wording is intended to provide more
precision in order to specify data interactions between threads.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Johannes Schaub

unread,
May 18, 2012, 8:23:05 PM5/18/12
to
Am 18.05.2012 23:11, schrieb Anand Hariharan:
> On May 17, 1:34 pm, Johannes Schaub<schaub.johan...@googlemail.com>
> wrote:
>> A comparison with a similar construct: If you change "x++" to "++x",
>> the behavior becomes defined in C++11:
>>
>> int x = 10;
>> x = ++x;
>>
>> Now there is an intuitive "dependency" on the result of "++x" and the
>> variable "x":
>
> Even when restricting this to the "intuitive" level, there is still a
> sequencing issue that the instruction to store the incremented value
> of x in x and the instruction to store the result of assignment in x
> have no relative ordering.
>

I agree to you. I wanted to make the reader aware that the compiler has
a sense of knowing that the right hand side of the assignment still
refers to x, so that it can be more cautious in sequencing these two
side effects (even when there would be no formal guarantees by C++11,
but indeed there are guarantees that make it valid). I guess this wasn't
a good example :)

> I would appreciate a reference (or a pointer or ... -- pun intended,
> of course) to a writeup about what the new C++ language standard has
> changed regarding sequence points -- that is (1) targeted to an
> audience of ordinary mortals and (2) authored by someone who is
> considered authoritative on the subject (*).
>
> thank you,
> - Anand
>
> (*) No, Johannes -- I am NOT implying you are not knowledgeable. What
> I mean is, I don't want URLs to some discussion form in some web forum
> just because a bunch of people clicked the "Like" or "+1" button.
>
>

Thanks for your caution, but I'm aware that I'm far from being
authorative on this subject. But just enough to answer this question. I
don't understand your discomfort with StackOverflow regarding this
though; if there is someone authorative who posts there and people +1 or
"Like" it, why do you not want an URL to it? There have been posts by
Herb, Anthony, Stroustrup, Howard and others on that site. This one is
by Anthony and concerns this subject:
http://stackoverflow.com/a/9581666/34509

Joshua Maurice

unread,
May 18, 2012, 8:23:49 PM5/18/12
to
On May 18, 6:05 am, PiotrN <piotr...@gmail.com> wrote:
>
> According to my theory:
>
> (x = (y = x)), (++x);
> OR without brackets:
> y = x, x = y, ++x;
> OR in pseudo assembly code:
> load r1, x // read from memory x to register r1
> store r1, y // store r1 in memory y
> load r1, y // not really necessary
> store r1, x
> load r1, x
> inc r1
> store r1, x
>
> So, results do not surprise me.
>
> I know that most people (and perhaps C++ standard) say that this is
> undefined behavior. But I'd prefer to believe that this is the way the
> most compiler interpret such things.

This is your problem. Consider:

int& f();
int& g();
int& h();
void foo()
{
f() = g() = h();
}

The question you need to ask is, which is called first? What is the
call order of f(), g(), and h()? In actuality in C++, you have no
guarantees. Allow me to rewrite this with some pseudo-code to
demonstrate.
f() = g() = h();
same as:
f() = (g() = h());
same as:
built_in_assignment( f() , built_in_assignment( g() , h() );
The general rule is that you do not have a guarantee as to the order
of evaluation of arguments. This is also true for most operators. (The
built-in operators || and && are an exception. Google "short
circuiting operators". The comma operator too. I forget if that's it.)

Your "theory" is simply not what the standard says, nor what compilers
give you.

Ike Naar

unread,
May 19, 2012, 2:46:30 AM5/19/12
to
On 2012-05-19, Joshua Maurice <joshua...@gmail.com> wrote:
> The general rule is that you do not have a guarantee as to the order
> of evaluation of arguments. This is also true for most
> operators. (The built-in operators || and && are an
> exception. Google "short circuiting operators". The comma operator
> too. I forget if that's it.)

The ?: operator too; in

X ? Y : Z

X is evaluated before Y or Z .

Francis Glassborow

unread,
May 19, 2012, 4:40:49 AM5/19/12
to
On 19/05/2012 07:46, Ike Naar wrote:
> On 2012-05-19, Joshua Maurice<joshua...@gmail.com> wrote:
>> The general rule is that you do not have a guarantee as to the order
>> of evaluation of arguments. This is also true for most
>> operators. (The built-in operators || and&& are an
>> exception. Google "short circuiting operators". The comma operator
>> too. I forget if that's it.)
>
> The ?: operator too; in
>
> X ? Y : Z
>
> X is evaluated before Y or Z .

and that or is an exclusive or, exactly one of the Y and Z
sub-expressions will be evaluated.

rado

unread,
May 22, 2012, 3:10:09 PM5/22/12
to
> You have invoked undefined behaviour because your assignment
> statement modifies x twice without an intervening sequence
> point. This is always a no no in C and C++ for built-in types. The
> same rule applies to struct/class types except that in most
> instances where it looks as this has been done (2 modifications to
> same memory between sequence points) there are some hidden sequence
> points because overloaded operators are actually function calls.

I wonder why decent compilers don't issue a warning in such cases. Or
maybe they do. Does anybody know?
-- Radoslav Getov

Pete Becker

unread,
May 22, 2012, 8:13:25 PM5/22/12
to
On 2012-05-22 19:10:09 +0000, rado said:

>>
>> You have invoked undefined behaviour because your assignment
>> statement modifies x twice without an intervening sequence
>> point. This is always a no no in C and C++ for built-in types. The
>> same rule applies to struct/class types except that in most
>> instances where it looks as this has been done (2 modifications to
>> same memory between sequence points) there are some hidden sequence
>> points because overloaded operators are actually function calls.
>
> I wonder why decent compilers don't issue a warning in such cases. Or
> maybe they do. Does anybody know?

It's rather pointless to warn about beginners' errors. The real cases
where this kind of thing bites you can't be recognized easily at
compile time, and beginners who got used to having their hands held
would find themselves suddenly lost without having developed the skills
to recognize the problem.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)


Francis Glassborow

unread,
May 22, 2012, 8:23:47 PM5/22/12
to
On 22/05/2012 20:10, rado wrote:
>> You have invoked undefined behaviour because your assignment
>> statement modifies x twice without an intervening sequence
>> point. This is always a no no in C and C++ for built-in types. The
>> same rule applies to struct/class types except that in most
>> instances where it looks as this has been done (2 modifications to
>> same memory between sequence points) there are some hidden sequence
>> points because overloaded operators are actually function calls.
>
> I wonder why decent compilers don't issue a warning in such cases. Or
> maybe they do. Does anybody know?
> -- Radoslav Getov

Well GNU GCC 4.7 with -Wall issues a warning

Ike Naar

unread,
May 22, 2012, 11:59:03 PM5/22/12
to
On 2012-05-22, rado <rge...@gmail.com> wrote:
>> You have invoked undefined behaviour because your assignment
>> statement modifies x twice without an intervening sequence
>> point. This is always a no no in C and C++ for built-in types. The
>> same rule applies to struct/class types except that in most
>> instances where it looks as this has been done (2 modifications to
>> same memory between sequence points) there are some hidden sequence
>> points because overloaded operators are actually function calls.
>
> I wonder why decent compilers don't issue a warning in such cases. Or
> maybe they do. Does anybody know?
> -- Radoslav Getov

$ cat a.c
int main(void)
{
int x = 10;
x = x++;
return 0;
}
$ gcc --version
gcc (GCC) 4.1.2 20061021 prerelease (NetBSD nb3 20061125)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -Wall a.c
a.c: In function 'main':
a.c:4: warning: operation on 'x' may be undefined
0 new messages