So you think you know C?
int i = 5;
i = ++i + ++i;
return i;
a) 12
b) 13
c) 14
d) Undefined int i = 5;
i = ++i + ++i;
return i;
a) 12
b) 13
c) 14
d) UndefinedFirstly, from Wikipedia
A sequence point defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.
-----
Secondly from Annex C of the C99 Standard: Sequence Points
1. The following are sequence points described in 5.1.2.4
- The call to a function, after the arguments have been evaluated (6.5.2.2).
- The end of the first operand of the following operators: logical AND && (6.5.13); logical OR || (6.5.14); conditional ? (6.5.17).
- The end of a full declarator: declarators (6.7.5);
- The end of a full expression: an initializer (6.7.8); the expression in an expression statement (6.8.3); the controlling expression for a while or do statement (6.8.5); each of the expressions fro a for statement (6.8.5.3); the expression in a return statement (6.8.6.4).
- Immediately before a library function returns (7.1.4).
- After the actions associated with each formatted input/output function conversion specified (7.19.6, 7.24.2).
- Immediately before and immediately after each call to a comparison function and also between any call to a comparison function and any movement of the object passed as arguments to the call (7.20.5).
-----
Now onto this statement
i = ++i + ++i;
lacking in sequence points between the double assignments is undefined and has been undefined for the life of the language. It is as undefined as all of it's ugly brethren and should be left to die.
Why does this question keep popping up?
Do you mean option D or D, the Language?
$ cat t.c ; gcc ./t.c
#include<stdio.h>
int main() {
printf("%d\n", a());
}
int a() {
int i = 5;
i = ++i + ++i;
return i;
}
$ ./a.out
14 # ??
$ gcc t.c -c -o t.bin
$ gdb t.bin
...
(gdb) disassemble a
Dump of assembler code for function a:
0x0000000000000030 <a+0>: push %rbp
0x0000000000000031 <a+1>: mov %rsp,%rbp
0x0000000000000034 <a+4>: movl $0x5,-0xc(%rbp)
0x000000000000003b <a+11>: mov -0xc(%rbp),%eax
0x000000000000003e <a+14>: add $0x1,%eax # add 1 and store it in i => 6
0x0000000000000041 <a+17>: mov %eax,-0xc(%rbp)
0x0000000000000044 <a+20>: mov -0xc(%rbp),%eax
0x0000000000000047 <a+23>: add $0x1,%eax # add 1 and store it in i => 7
0x000000000000004a <a+26>: mov %eax,-0xc(%rbp)
0x000000000000004d <a+29>: mov -0xc(%rbp),%eax
0x0000000000000050 <a+32>: mov -0xc(%rbp),%ecx # move current value of i (7) into %ecx and %eax (both registers are now 7)
0x0000000000000053 <a+35>: add %ecx,%eax # add them together => 14
0x0000000000000055 <a+37>: mov %eax,-0xc(%rbp)
...In other words, the very definition of undefined behavior; You cannot reason about how the program will behave. This topic has already been covered fairly well on SO: http://stackoverflow.com/questions/949433/could-anyone-expla...
A nontrivial example is the value of "-64 >> 3". More info at http://stackoverflow.com/questions/2397984/undefined-unspeci...
I think the post you reply to refers to the fact that early K&R C predates any standard that introduced the term 'undefined behavior'. At that time, the standard was just 'whatever that tool Kernighan and Ritchie wrote does'.
The maxim then (and now) being: Don't Write Silly Code.
PS why, are you having hiring difficulties or something?
By the way your answer is wrong.
The C spec doesn't handle this case. The only correct answer is undefined.