This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
#include<stdio.h>
int main()
{
int i=2;
printf("%d %d\n",++i,++i);
return 0;
}
Output is 4 4 on gcc.
Please explain this output
This is undefined behaviour. The order of evaluation of the function parameters is not defined by the C standard.
Relevant sections: C99 Section 6.5.2.2 Paragraph 10
The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is
unspecified, but there is a sequence point before the actual call.
also in C99 Section 6.5.2.2 Paragraph 10
There is a sequence point after the evaluations of the function
designator and the actual arguments but before the actual call. Every
evaluation in the calling function (including other function calls)
that is not otherwise specifically sequenced before or after the
execution of the body of the called function is indeterminately
sequenced with respect to the execution of the called function.94)
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Parameter evaluation order before a function calling in C
(7 answers)
Closed 1 year ago.
Can someone please explain why the output here is 2 1 1, what does c prioritise here? how come the output of i++ is 1. Thanks in advance
~
#include <stdio.h>
void main(){
int i=1;
int *p=&i;
printf("%d%d%d\n",*p,i++,i);
}
The behavior of this code is not defined by the C standard per C 2018 6.5 2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined…
i++ has the side effect of updating i with its incremented value. The function call arguments also include *p and i, both of which refer to i and use its value. i is a scalar object. The order of evaluation of function call arguments and their side effects are unsequenced (meaning the C standard does not impose any ordering requirements on them). Therefore, all the conditions for the rule above are met, so the behavior is not defined by the C standard.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 6 years ago.
int c=2; printf("%d %d %d",c,c<<=2,c>>=2);
Is this undefined behavior ?
int c=2;
printf ("%d %d %d",c,c<<=2,c>>=2);
The behaviour is undefined.
[C99: 4/2]: If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.
[C99: 5.1.2.3/2]: Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (A summary of the sequence points is given in annex C.)
[C99: C/1]: The following are the sequence points described in 5.1.2.3:
- 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.15); comma , (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 of a selection statement (if or switch) (6.8.4); the controlling expression of a while or do statement (6.8.5); each of the expressions of 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 specifier (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 objects passed as arguments to that call (7.20.5).
[C99: 6.2.2.2/10]: The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
And, although I can't prove a negative, there is no wording to make an exception for the varargs case.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
Can anyone please explain me the correct logic behind the output for following code.
#include <stdio.h>
int main()
{
int a=1;
printf("%d\t%d\t%d\n",a,a++,++a);
return 0;
}
Expected output is 3 2 3
Your code is undefined behavior, so there is no such thing as "correct logic" for it --- it could output 0 0 0, 1 1 2, hello, world, or emit nasal demons.
From C99 standard:
Section 6.5, paragraph 2:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
Section 6.5.2.2, paragraph 10:
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
This question already has answers here:
Parameter evaluation order before a function calling in C
(7 answers)
Undefined behavior and sequence points
(5 answers)
Closed 8 years ago.
#include<stdio.h>
int main()
{
int i = 2;
printf("\n %d %d %d \n",--i,i--,i); // 0 2 2
return 0;
}
The output prints 0 2 0 and not 0 2 2.I couldn't understand, as I assumed that the printf() evaluates from right to left.
Your code exhibits Unspecified behaviour. As per c99 standard document, chapter 6.5.2.2, paragraph 10:
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
Again, this shows undefined behaviour, because, i is getting modified more than once between two sequence points. As per chapter 6.5 paragraph 2:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
printf evaluates nothing. It is the compiler that evaluates arguments of a function (that is it is the compiler that generates the object code) and the order in which the arguments will be evaluated in C is unspecified. So the compiler may evaluates them in any order.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
Can someone please explain why this code is outputing 2 1, I thought post-increment was supposed to be applied after the printf instruction.
#include <stdio.h>
int main() {
int i=1;
int *p=&i;
printf("%d %d\n", *p ,i++);
return 0;
}
The order of evaluation of is not specified for this case in the standard and so you can not determine whether *p or i++ will be evaluated first. The C99 draft standard says in section 6.5.2.2 Function calls paragraph 10 says:
The order of evaluation of the function designator, the actual arguments, and
subexpressions within the actual arguments is unspecified, but there is a sequence point
before the actual call.
This is also undefined behavior because you are modifying i and accessing the previous value of i in another expression within the same sequence point, the draft standard in section 6.5 Expressions paragraph 2 says:
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression.72) Furthermore, the prior value
shall be read only to determine the value to be stored
Comma is a sequence point, but not in function calls.
And printf is a function with arguments separated with commas.
In expression like this:
if(i+2,i++). . . comma is a sequence point and assures that expressions will be evaluated from left to right, and final value of expression will be value of rightmost sub-expression. In this case i++.
On the other hand in funcion call:
function(i+1,i++,i--) comma in not a sequence point and any of sub-expressions can be evaluated as first. The only thing sure is that they all be evaluated, but not in any specific order.