Cached at:
05/14/26, 06:25 PM
# int a = 5; a = a++ + ++a; a = ?
Source: [https://gynvael.coldwind.pl/?id=372](https://gynvael.coldwind.pl/?id=372)
I've received the title riddle from furio and I found it interesting enough to pass it during the next few days to everyone that might be even remotely interested in C/C\+\+ problems\. The interesting thing here is the Undefined Behavior \(UB\), well\.\.\. actually two UBs, thanks to which there are three possible correct answers: 11, 12 and 13\.
Let's start with theoretical considerations on the possible answers and then get to empirical results \(initially gathered by nism0, but later extended by readers from[the Polish side of the mirror](https://gynvael.coldwind.pl/?id=369)\)\.
OK\.\.\. so, which places are UB/unknown/compiler\-dependent?
**First UB** First, we don't know which**a**will get fetched first \(by*fetching*I mean copying the value from memory to some internal register\)\. There are two possibilities here:
Possibility 1\. The first**a**will get fetched first, then the pre\-increment will take place, and then the second**a**will be fetched \(I'll skip the post\-incrementation problem for now\): `a = a \+ \+\+a;`
`Step 1\. Fetch first a\.a = 5 \+ \+\+a; \(a==5\)`
`Step 2\. Pre\-increment a\.a = 5 \+ a; \(a==6\)`
`Step 3\. Fetch second a\.a = 5 \+ 6; \(a==6\)`
`Step 4\. Calculate the addition\.a = 11;`
Possibility 2\. The pre\-increment will take place first and the result will be stored in memory, and then the fetching of**a**will take place\.
`a = a \+ \+\+a;Step 1\. Pre\-increment a\.a = a \+ a; \(a==6\)Step 2 i 3\. Fetching both a\.a = 6 \+ 6; \(a==6\)Step 4\. Calculate the addition\.a = 12;`
So, even with skipping the post\-incrementation we get two different possibilities \(11 and 12\)\.**Second UB** The second UB is related to the post\-incrementation and the potentially trivial line**a = a\+\+**\. As it occurs, there are also two possibilities here \(I'll demonstrate them using**int a = 5; a = a\+\+;**as an example\)\.
Terminology: **a\_mem**\-**a**still in memory \(e\.g\. as a local variable somewhere on the stack\) **a\_copy**\- a previously fetched copy of**a**in some internal register
Possibility 1\. Post\-increment goes Missing In Action: `Initial setup: \(a\_mem == 5, a\_copy == n/a\)`
`Step 1\. Fetching a\.a = 5\+\+; \(a\_mem == 5, a\_copy == 5\)`
`Step 2\. Post\-increment on the variable \(in memory\)\.a = 5; \(a\_mem == 6, a\_copy == 5\)`
`Step 3\. "Set" gets executed \- a\_copy is moved to a\_mem\.\(a\_mem == 5, a\_copy == n/a\)`
In the above case the result of post\-incrementation went MIA \- it got written to the memory but it was soon overwritten by another \(not incremented\) value\. \(Actually I've always thought that post\-increment is always done after all operations finish so personally I would treat this behavior as a compiler bug\.\)Possibility 2\. Post\-incrementation is deferred to the very end\. `Initial setup: \(a\_mem == 5, a\_copy == n/a\)`
`Step 1\. Fetching a\.a = 5\+\+; \(a\_mem == 5, a\_copy == 5\)`
`Step 2\. "Set" gets executed \- a\_copy is moved to a\_mem\.\(a\_mem == 5, a\_copy == n/a\)`
`Step 3\. Post\-increment on the variable \(in memory\)\.a\+\+ \(a\_mem == 6, a\_copy == n/a\)`
So, the post\-increment is executed at the very end of the calculations and it does not get overwritten\.**Summary of UBs** To sum up the two previously described UBs for the**a = a\+\+ \+ \+\+a**equation we get: Possibilities 1 i 1: 5\+6 and the post\-increment goes MIA,**result: 11** Possibilities 2 i 1: 6\+6 and the post\-increment goes MIA,**result: 12** Possibilities 1 i 2: 5\+6 and the post\-increment is deferred,**result: 12** Possibilities 2 i 2: 6\+6 and the post\-increment is deferred,**result: 13**
**Experimental results** Now for the empirical results \(thx to nism0 for the initial tests and the initial table, and to nonek and qyon for spotting certain typos\):
Code 1Code 2Code 3Code 4Code 5Code 6int a = 5;
a = a\+\+ \+ a\+\+;int a = 5;
a = a\+\+ \+ \+\+aint a = 5;
a = \+\+a \+ a\+\+;int a = 5;
a = \+\+a \+ \+\+a;int a = 5;
a = a\+\+;int a = 5;
a = a \+ \+\+a;
Compiler/LangVer\.Result 1Result 2Result 3Result 4Result 5Result 6gcc2\.9512131413612gcc4\.112131413612gcc4\.212131413612gcc4\.2\.1 Apple12131413612gcc4\.312131413612gcc4\.3\.312131314612gcc4\.4\.412131314612gcc4\.6\.0 \(exp\.\)12131413612gcc4\.5\.1 MinGW6412131314612tcc0\.9\.25????????512bcc0\.16\.17????????512Microsoft C/C\+\+16\.00\.30319\.01 \(80x86\)12131314612Embarcadero C\+\+6\.31 for Win3212131314612Intel C\+\+12\.0\.1\.12712131313612Keil C9\.0211121213612SDCC3\.0\.1 \#609211121314512clang2\.811121213511clang1\.6 Apple11121213511PHP5\.2\.1011121213512java1\.6\.0\_0611121213511javac1\.4\.2\_1211121213511java1\.6\.0\_2111121213511javac1\.6\.0\_2211121213511C\#2\.011121213511C\#4\.011121213511C\#Mono 2\.6\.411121213511Borland Turbo C\+\+ for DOS2\.0112131314612HiSoft C for ZX Spectrum1\.311121213512Thanks for additional results to:[Icewall](http://icewall.pl/),[Krzysztof Kotowicz](http://blog.kotowicz.net/)\(PHP 5\.2\.10\), mlen \(2x clang, 2x gcc\), none'a \(2x Java\),[Keraj](http://keraj.net/)\(2x Java\), MDobak \(SDCC & Keil C\), garbaty lamer \(3x C\#, Turbo C\+\+, HiSoft C\), Xgrzyb90 \(gcc 4\.4\.4\), no\_name \(gcc 4\.3\.3\), dikamilo \(mingw64 4\.5\.1\)
Garbaty lamer has also posted \(in the comments on the Polish side of the mirror\) a really cool screenshot from the**HiSoft C for ZX spectrum**\(click to zoom\):
[](https://gynvael.coldwind.pl/img/hisoftgynvael_garbaty_lamer.png)
If you would like to test your compiler \(posting back the results in the comments is really appreciated, especially from strange/uncommon compilers and other languages which support pre\- / post\- increments ;\>\) you can use the code \(made by nism0\) at the bottom of the post \(see Appendix 3\)\.
And that's that ;\>
**Appendix 1:** In the comments on[the Polish side of the mirror](https://gynvael.coldwind.pl/?id=369)Rolek has suggested to apply the same test to overloaded operators \(see the comments on the Polish side for the code\)\. Results \(by Rolek from MSVC\+\+ and me from g\+\+\):
Code 1Code 2Code 3Code 4Code 5Code 6int a = 5;
a = a\+\+ \+ a\+\+;int a = 5;
a = a\+\+ \+ \+\+aint a = 5;
a = \+\+a \+ a\+\+;int a = 5;
a = \+\+a \+ \+\+a;int a = 5;
a = a\+\+;int a = 5;
a = a \+ \+\+a;
Compiler/Lang\.Ver\.Result 1Result 2Result 3Result 4Result 5Result 6Microsoft C/C/\+\+ \(w/o overloading\)16\.00\.30319\.01**12**13**13**14**6**12Microsoft C/C/\+\+ \(with overloading\)16\.00\.30319\.01**11**13**12**14**5**12g\+\+ \(w/o overloading\)4\.5\.0 MinGW**12**13**13**14**6**12g\+\+ \(with overloading\)4\.5\.0 MinGW**11**13**12**14**5**12Also, krlm has posted a link to a good article about[sequence points](http://en.wikipedia.org/wiki/Sequence_point)\.
**By the way\.\.\.** If want to improve your binary file and protocol skills, check out the workshop I'll be running between April and June →[Mastering Binary Files and Protocols: The Complete Journey](https://hackarcana.com/workshop-session/2025-Q1-Q1-mastering-binary/buy?utm=gyn-blog-inad)
**Appendix 2:** Garbaty lamer \(again, on[the Polish side of the mirror](https://gynvael.coldwind.pl/?id=369)\) has mentioned that in C\# this riddle isn't actually a riddle \- it's well defined behavior, see C\# specification point §7\.3: *Operands in an expression are evaluated from left to right\. For example, in F\(i\) \+ G\(i\+\+\) \* H\(i\), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i\. This is separate from and unrelated to operator precedence\.*
**Appendix 3:** Code for testing: `\#include <stdio\.h\>`
`int main\(void\)\{ int a = 5, b = 5, c = 5, d = 5, e = 5, f = 5;`
`// test 1 a = a\+\+ \+ a\+\+; printf\("%i \\n",a\);`
`// test 2 b = b\+\+ \+ \+\+b; printf\("%i \\n",b\);`
`// test 3 c = \+\+c \+ c\+\+; printf\("%i \\n",c\);`
`// test 4 d = \+\+d \+ \+\+d; printf\("%i \\n",d\);`
`// test 5 e = e\+\+; printf\("%i \\n",e\);`
`// test 6 f = f \+ \+\+f; printf\("%i \\n",f\);`
`// done return 0;\}`
**Appendix 4:** A comment from Cem Paya: \-\-start\-\- Similar to C\#, this is also not a riddle for Java because Java defines evaluation to be strictly left\-to\-right\. See section 15\.7 here for some examples with side\-effects as in your case: [http://java\.sun\.com/docs/books/jls/second\_edition/html/expressions\.doc\.html](http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html) In C\+\+ where it is undefined, the result can also depend on the optimization level used during compilation, which can change the number of times a value is referenced\. eg the compiler expects "a" to not change its value during the evaluation and may optimize other occurences to the same one it fetched\. ==end==