post increment,pre increment and operator precedence [duplicate] - c

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
the answer is coming out to be 45.I cant understand how this thing is working.
main()
{
int a =10;
int i = a++ + ++a + a++ + ++a;
printf("%d , %d ", i,a);
}

Actually the output is an undefined behavior which is fine.
From the C99 standard are 6.5 Expressions, §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.
The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined.

Related

A 7 Line Simple C Code That I Can't Figure Out [duplicate]

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.

printf() function evaluation of pre and post decrements in C [duplicate]

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.

Order of evaluation of subexpressions [duplicate]

This question already has answers here:
Is the behaviour of i = i++ really undefined?
(9 answers)
Closed 8 years ago.
If the order of evaluation of sub expressions is not guaranteed, then why is this correct?
int a = 1;
a = a + 1;
Here the compiler could evaluate first a and then a + 1 so a can be 1 or 2
while this is not:
a = a++;
Here the compiler could evaluate first a and then a++ son a can be 1 or 2.
What's the difference?
It is undefined behavior. The reason follows::
The Standard in §5/4 says
Between the previous and next sequence point a scalar object shall
have its stored value modified at most once by the evaluation of an
expression.
and
The prior value shall be accessed only to determine the value to be
stored.
It means, that between two sequence points a variable must not be modified more than once and, if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written.
Read about sequence points here , basically you have 2 assignments between 2 sequence points and that will cause undefined behavior.
a++ will increment value for a and then assign it to a and another assignment will be done by = operator, while a + 1 will not change value for a and you will have only 1 assignment between 2 sequence points

Array subscription execution order [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
How this code fragment work for array subscription execution direction.
Please explain.
static int a[][2][3]={0,1,2,3,4,5,6,7,8,9,10,11,12};
int i=-1;
int d;
d=a[i++][++i][++i];
printf("%d",d);
This invokes undefined behaviour. Quoting C99 standard §6.5 ¶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.
There is no sequence point in the evaluation of the array index in
d = a[i++][++i][++i];
Therefore, it's not known when the side effects of evaluation of expressions in [] will take place. Quoting C99 stanadard again §6.5.2.1 ¶2
The definition of the subscript operator [] is that E1[E2] is
identical to (*((E1)+(E2))).
Therefore, the expression a[i++][++i][++i] evaluates to
a[i++][++i][++i]
== *((a[i++][++i]) + (++i))
== *(*((a[i++]) + (++i)) + (++i))
== *(*(*(a + i++) + (++i)) + (++i))
Adding parentheses does not create a sequence point. It only defines the order of evaluation of sub-expressions of the complete expressions. It does not guarantee when the side effects of evaluating the sub-expression will take place.
a[i++][++i][++i]
This statement results in undefined behaviour.
you can try executing code here and you will get different output than 2 that you got. Its not that you will not get output but the behaviour is undefined so you cant predict the output.

post increment and pointer in printf [duplicate]

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.

Resources