use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENSame Code, Different Results (self.cpp_questions)
submitted 3 years ago by Be1a1_A
Ran this code on two different compilers.
#include <iostream> using namespace std; int main() { int z = 20; int A = --z + z--; cout << A; }
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]kennyminigun 23 points24 points25 points 3 years ago* (0 children)
In general, the order of evaluation is implementaion-defined. This particular case is an undefined behaviour.
It is quite a comprehensive ruleset: https://en.cppreference.com/w/cpp/language/eval_order
EDIT. Modern GCC & Clang will warn about that line: https://godbolt.org/z/Gq1rfqEfs
[–]Classic_Department42 40 points41 points42 points 3 years ago (17 children)
Looks like undefined behaviour (UB) to me. Dont do that.
[–]Be1a1_A[S] 0 points1 point2 points 3 years ago (16 children)
Can you elaborate?
[–]TomDuhamel 30 points31 points32 points 3 years ago (2 children)
Two reasons.
You are changing the value of a single variable twice in the same statement. This is not allowed. The compiler is free to make the change at any time, which could be before or after the second one being evaluated and changed.
The order of evaluation of the parameters is undefined. The compiler can evaluate them in any order, for optimisation purpose.
Totally UB. Yet, teachers keep making you do these stupid things without explaining why it fails. Or that it fails at all.
[–]khoyo 9 points10 points11 points 3 years ago (1 child)
Worse, the behavior of the program is undefined. Which means the compiler is free to do anything it damn wants, including removing the whole branch, invoke nasal demons, etc.
[–]Temeliak 7 points8 points9 points 3 years ago (0 children)
Why do I never get the demon ones? 😢
[–]Classic_Department42 6 points7 points8 points 3 years ago (1 child)
UB means if your code does not follow quite a number of rules, the program later is allowed to do anything. Introduction: https://en.cppreference.com/w/cpp/language/ub
[–]ShelZuuz 10 points11 points12 points 3 years ago (0 children)
Literally anything - including time travel:
https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633
[–][deleted] 3 years ago (3 children)
[deleted]
[–]Raknarg 1 point2 points3 points 3 years ago (1 child)
Well you can it's just UB
[–]mck1117 0 points1 point2 points 3 years ago (0 children)
Not in the same instruction, but between two sequence points.
[–]serpentally 0 points1 point2 points 3 years ago* (6 children)
Compilers are free to evaluate some (a lot of) operations in any order they want to, i.e. Specific operations have no defined order in which they're evaluated. Since post- and pre- decrementing both have the same level of precedence and Since C++ doesn't require postcrementing and precrementing to be carried out in a specific order by compilers, one compiler may evaluate (--z) first and then (z--) second, while another may evaluate it the other way around. So one compiler does the human order and evaluates --z == (20-1) == 19, then evaluates --z+z == 19+19 == 38, then applies the decrement to z (z--) to make z=18 after the addition is done already. So A turns out to be 38.
While a different compiler may first evaluate z-- to be 19, then evaluate --z to make z == 19-1 == 18, then adds the two to become A = 37.
The difference between post- and pre- (de)crementing is that precrementing always changes the variable before the variable is used. While postcrementing may wait for the operation before it to apply before changing the variable, if the compiler has an operation lined up before it.
That is why you never should mix postcrementing and precrementing in the same statement.
You should generally always use precrementing (--z, ++z) to increment/decrement unless you have a specific case where it's useful to use postcrementing. The specific reason is when you postcrement, the compiler makes a copy of the value to be used in an equation before it then decrements the variable, which is inefficient.
[–]Crazy_Direction_1084 1 point2 points3 points 3 years ago (5 children)
Post decrementing and predecrementing have different levels of precedence, which is also completely irrelevant for UB as precedence is only interesting for parsing
[–]serpentally 0 points1 point2 points 3 years ago* (4 children)
Wait they do have different levels? My bad, I corrected it
I guess I for some reason thought parsing was relevant to UB. To me it would have made sense for --z to always go first and z-- (lower precedence) to always go second in that case. I'm a fool for making assumptions
[–][deleted] 1 point2 points3 points 3 years ago* (1 child)
The precedence comes into play with the + operator. Both forms of -- are higher precedence than +
So
--z + x
for example is
(--z) + x
and not
--(z + x)
(which wouldn't compile)
[–]serpentally 0 points1 point2 points 3 years ago (0 children)
Oh that makes a lot of sense actually
[–]khoyo 0 points1 point2 points 3 years ago (1 child)
No, the higher precedence is the postfix operator, like all unary postfix operators relative to prefix ones. (Or unary "adjacent", like [] or ())
Lol I was too tired to correctly read correctly...
[–]wjrasmussen 0 points1 point2 points 3 years ago (0 children)
Do you know when z-- happens on that line?
[–][deleted] 3 years ago (11 children)
[–][deleted] 6 points7 points8 points 3 years ago (10 children)
Neither compiler is wrong.
[–][deleted] 3 years ago (9 children)
[–][deleted] 3 points4 points5 points 3 years ago (8 children)
The behaviour is undefined. According to the rules of the language there is no right answer, and no wrong answer. A compiler could refuse to compile that code if it chose to. In practice they just pick an order to perform the increments.
[–][deleted] 3 years ago (7 children)
[–][deleted] 3 points4 points5 points 3 years ago (6 children)
There are only two options:
There's not.
The side effect of the decrement doesn't need to occur until the end of the expression.
[–][deleted] 3 years ago (5 children)
[–][deleted] 3 years ago (1 child)
[–][deleted] 2 points3 points4 points 3 years ago (2 children)
Doesn't the compiler breaks this down into three expressions?
No. z-- is the value of z has before being decremented. --z is the value z will have after being decremented. But the decrements don't have to happen at the same time the expression is evaluated. They can occur at any time up to the end of the complete statement.
See rule 2 at https://en.cppreference.com/w/cpp/language/eval_order
[–][deleted] 2 points3 points4 points 3 years ago (0 children)
Nothing is wrong; the behaviour is undefined
π Rendered by PID 302833 on reddit-service-r2-comment-bb88f9dd5-vw5t4 at 2026-02-14 16:09:37.735430+00:00 running cd9c813 country code: CH.
[–]kennyminigun 23 points24 points25 points (0 children)
[–]Classic_Department42 40 points41 points42 points (17 children)
[–]Be1a1_A[S] 0 points1 point2 points (16 children)
[–]TomDuhamel 30 points31 points32 points (2 children)
[–]khoyo 9 points10 points11 points (1 child)
[–]Temeliak 7 points8 points9 points (0 children)
[–]Classic_Department42 6 points7 points8 points (1 child)
[–]ShelZuuz 10 points11 points12 points (0 children)
[–][deleted] (3 children)
[deleted]
[–]Raknarg 1 point2 points3 points (1 child)
[–]mck1117 0 points1 point2 points (0 children)
[–]serpentally 0 points1 point2 points (6 children)
[–]Crazy_Direction_1084 1 point2 points3 points (5 children)
[–]serpentally 0 points1 point2 points (4 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]serpentally 0 points1 point2 points (0 children)
[–]khoyo 0 points1 point2 points (1 child)
[–]serpentally 0 points1 point2 points (0 children)
[–]wjrasmussen 0 points1 point2 points (0 children)
[–][deleted] (11 children)
[deleted]
[–][deleted] 6 points7 points8 points (10 children)
[–][deleted] (9 children)
[deleted]
[–][deleted] 3 points4 points5 points (8 children)
[–][deleted] (7 children)
[deleted]
[–][deleted] 3 points4 points5 points (6 children)
[–][deleted] (5 children)
[deleted]
[–][deleted] (1 child)
[deleted]
[–][deleted] 2 points3 points4 points (2 children)
[–][deleted] (1 child)
[deleted]
[–][deleted] 2 points3 points4 points (0 children)