ambiguity of post-increment and post-decrement

M

Mark Turney

I was reading "Practical C++ Programming" yesterday, and it mentioned
that the order of execution for post-increment and post-decrement
operators was ambiguous.
I had previously learned that a post-increment or post-decrement
operator modifies the operand once the entire statement has been
executed, not during execution of the statement, so this confused me.

An examples given to illustrate the ambiguity is:
a = i++; // may increment i before or after a is evaluated.

I tested with the VC6 compiler and the gnu compiler, but with the same
results: the post-decrement occurs after the entire statement is
executed, not during it's execution.

I have now been told that the actual ANSI C++ Standard is ambiguous
concerning execution order (regardless of what occurs during
compilation with different compiler makers).

I am still in the process of working my way through C++ and I don't
have a copy of the official standard, so I was hoping a more learned
individual would be able to elucidate this troublesome issue for me.
"Pracitcal C++ Programming" recommends against the use of increment
and decrement operators within statements, but I've learned to really
enjoy them.

Thanks for the help
-mark
 
G

Gianni Mariani

Mark said:
I was reading "Practical C++ Programming" yesterday, and it mentioned
that the order of execution for post-increment and post-decrement
operators was ambiguous.
I had previously learned that a post-increment or post-decrement
operator modifies the operand once the entire statement has been
executed, not during execution of the statement, so this confused me.

An examples given to illustrate the ambiguity is:
a = i++; // may increment i before or after a is evaluated.

I tested with the VC6 compiler and the gnu compiler, but with the same
results: the post-decrement occurs after the entire statement is
executed, not during it's execution.

I have now been told that the actual ANSI C++ Standard is ambiguous
concerning execution order (regardless of what occurs during
compilation with different compiler makers).


Not quite "ambiguous", more like "undefined". The standard does not
specify what the compiler should do hence you can't depend on a
particular behaviour for code portability.

// this code is 100% portable and likely just as fast
a = i; ++ i;
I am still in the process of working my way through C++ and I don't
have a copy of the official standard, so I was hoping a more learned
individual would be able to elucidate this troublesome issue for me.
"Pracitcal C++ Programming" recommends against the use of increment
and decrement operators within statements, but I've learned to really
enjoy them.

look up references for "sequence points". These are points where all
the side effects should be complete. The ";" at the end of an
expression is usually a good place to look.
 
K

Karl Heinz Buchegger

Mark said:
I was reading "Practical C++ Programming" yesterday, and it mentioned
that the order of execution for post-increment and post-decrement
operators was ambiguous.
I had previously learned that a post-increment or post-decrement
operator modifies the operand once the entire statement has been
executed, not during execution of the statement, so this confused me.

An examples given to illustrate the ambiguity is:
a = i++; // may increment i before or after a is evaluated.

I tested with the VC6 compiler and the gnu compiler, but with the same
results: the post-decrement occurs after the entire statement is
executed, not during it's execution.

I have now been told that the actual ANSI C++ Standard is ambiguous
concerning execution order (regardless of what occurs during
compilation with different compiler makers).


Ambigous is the wrong word. It is simply undefined when the increment
actually happens. All you know is that when the next sequence point
is reached (in the above case this is the end of the statement, the ';')
the increment has happend. But when exactly is undefined.
"Pracitcal C++ Programming" recommends against the use of increment
and decrement operators within statements, but I've learned to really
enjoy them.

There is nothing wrong with them. Your program just must not depend
on some specific execution order, that's all.
 
R

Ron Natalie

Karl Heinz Buchegger said:
Ambigous is the wrong word. It is simply undefined when the increment
actually happens.

It's just simply undefined what happens.
 
J

Jack Klein

I was reading "Practical C++ Programming" yesterday, and it mentioned
that the order of execution for post-increment and post-decrement
operators was ambiguous.
I had previously learned that a post-increment or post-decrement
operator modifies the operand once the entire statement has been
executed, not during execution of the statement, so this confused me.

You think you learned that, you are wrong.
An examples given to illustrate the ambiguity is:
a = i++; // may increment i before or after a is evaluated.


As others have pointed out, this is just plain undefined behavior.
Within a single expression without a sequence point, you are allowed
to modify an object only once, and access its original value only for
the purpose of deriving the new value.
I have now been told that the actual ANSI C++ Standard is ambiguous
concerning execution order (regardless of what occurs during
compilation with different compiler makers).

The word "ambiguous" is ambiguous in this context. It is not defined
by the C++ standard.
I am still in the process of working my way through C++ and I don't
have a copy of the official standard, so I was hoping a more learned
individual would be able to elucidate this troublesome issue for me.
"Pracitcal C++ Programming" recommends against the use of increment
and decrement operators within statements, but I've learned to really
enjoy them.

Thanks for the help
-mark

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
D

David Fisher

Mark Turney said:
I had previously learned that a post-increment or post-decrement
operator modifies the operand once the entire statement has been
executed, not during execution of the statement, so this confused me.

An examples given to illustrate the ambiguity is:
a = i++; // may increment i before or after a is evaluated.

"Pracitcal C++ Programming" recommends against the use of increment
and decrement operators within statements, but I've learned to really
enjoy them.

I'm not sure if you meant that increment and decrement operators
_themselves_ are bad - there is no problem if "i" is not mentioned twice in
the same statement. The statement:

a[j] = i++;

causes no problems at all ...

Another "undefined" example is in a function call like f(i, i++), but just
f(i++) would be OK.

David F
 
R

Risto Lankinen

Hi!

First law of Internet thermodynamics:

"Every flame has an equally strong but opposite counterflame."

For instance, if you post a flame about grammar or spelling,
the probability that your article has at least one grammatic or
spelling error is asymptotically equal to 1 .

Now, let's see if one exists here...

Artie Gold said:
`Ambigous' isn't even a word! Can't you spel?

Ah! Science is wonderful!

- Risto -
 
A

Artie Gold

Risto said:
Hi!

First law of Internet thermodynamics:

"Every flame has an equally strong but opposite counterflame."

For instance, if you post a flame about grammar or spelling,
the probability that your article has at least one grammatic or
spelling error is asymptotically equal to 1 .

Now, let's see if one exists here...




Ah! Science is wonderful!

- Risto -

Alas, you failed to quote my closing [ ;-) ]...

So there!

[;-)]

--ag
 
M

Mark Turney

I want to thank everyone for clearing up my errant understanding of
post-increment and post-decrement operators.

-mark
 
Joined
Nov 13, 2006
Messages
2
Reaction score
0
David Fisher said:
"Mark Turney" <[email protected]> wrote:

Another "undefined" example is in a function call like f(i, i++), but just
f(i++) would be OK.

David F


I am not so sure... With g++:

int x = 0;
f( x++ ); // compiler generates: f( 0 ); x=x +1;

Now, either the standard defines the precedence of the function call over the increment, in which case both f(i,i++) and f(i++) are well defined, or the standard does not define the ordering of this two instructions so both are ill defined (*)

Also, in some languages (example: c++) the implementation of post-incrementmay need an extra copy operation that is unneeded. (See Alexander Alexandrescu's 'Modern C++ Design' for more insight, basically a post-increment operator must copy the object, increment de original and return the copy to the caller, while a preincrement just increments the original and returns it's reference).

David

* Another option would be the standard defining that the post-increment must happen before function calls, in that case your example would be correct, but g++ would not comply with this part of the standard. I would assume that g++ does not differ from the standard in this point anyway.
 
Joined
Nov 13, 2006
Messages
2
Reaction score
0
David Fisher said:
"Mark Turney" <[email protected]> wrote:
Another "undefined" example is in a function call like f(i, i++), but just
f(i++) would be OK.

David F

I am not so sure... With g++:

int x = 0;
f( x++ ); // compiler generates: f( 0 ); x=x +1;

Now, either the standard defines the precedence of the function call over the increment, in which case both f(i,i++) and f(i++) are well defined, or the standard does not define the ordering of this two instructions so both are ill defined and I'll settle for the first: both are ill defined (*)

Also, in some languages (example: c++) the implementation of post-incrementmay need an extra copy operation that is unneeded. (See Alexander Alexandrescu's 'Modern C++ Design' for more insight, basically a post-increment operator must copy the object, increment de original and return the copy to the caller, while a preincrement just increments the original and returns it's reference).

David

* Another option would be the standard defining that the post-increment must happen before function calls, in that case your example would be correct, but g++ would not comply with this part of the standard. I would assume that g++ does not differ from the standard in this point anyway.

PD. Some other interesting examples with g++:
void g( int x, int y ) { std::cout << x << "," << y << std::endl; }

x = 0; g( x, x++ ); // prints 1,0
x = 0; g( x++, x ); // prints 0,1
x = 0; g( ++x, x ); x = 0; g( x, ++x ); // both print 1,1, does not mean you can depend on it though

Even if you could depend on the order that the compiler generates instructions, the two calls with post-increment yield results that are not easy to foresee from a human point of view, making maintenance costs raise.
 
Last edited:

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,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top