Please explain output of given program. [duplicate] - c

This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 6 years ago.
the code is given below:
it gives output true2.
#include<stdio.h>
int main()
{
int a=10;
if(a==a--)
printf("true 1\t");
a=10;
if(a==--a)
printf("true2 \t");
return 0;
}

The comparison done in both of the if statements result in undefined behaviour. So, anything could happen. Because a is read and modified without an intervening sequence point. The comparison operator == doesn't introduce a sequence point. You probably need to learn about undefined behaviour and sequence points, etc to understand the problem better.
Modern compilers may also help you. For example, Clang issues:
warning: unsequenced modification and access to 'a' [-Wunsequenced]
if(a==a--)
~ ^
warning: unsequenced modification and access to 'a' [-Wunsequenced]
if(a==--a)
~ ^
for the two if statements (GCC also produces similar warnings with gcc -Wall -Wextra).

In general, it is not a good practice to do a-- (or --a) inside a condition, because it is not clear to read.
In order to understand the difference between a-- and --a please see the answer at: Incrementing in C++ - When to use x++ or ++x?

Related

Pre and post increment confusion [duplicate]

This question already has answers here:
printf and ++ operator [duplicate]
(5 answers)
Closed 3 years ago.
I tried running this program :
#include<stdio.h>
int main(){
int a=5;
printf("%d %d", ++a,a++);
return 0;
}
with gcc in arch-chroot on a armv7 device. I expect to get output 7 5 but i'm getting 7 6. Can anyone explain what's going on?
Your code is invoking Undefined Behavior (UB)!
Use the warning flgas -Wall -Wextra during compilation, and the compiler will tell you the story:
prog.c: In function 'main':
prog.c:4:30: warning: operation on 'a' may be undefined [-Wsequence-point]
4 | printf("%d %d", ++a,a++);
| ~^~
7 5
In that online demo, I got a different output, a characteristic of UB.
Read more in printf and ++ operator.
6.5p2
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. If there are multiple allowable orderings of the
subexpressions of an expression, the behavior is undefined if such an
unsequenced side effect occurs in any of the orderings.84)
++a and a++ are unsequenced. Your program is ill-formed.

C - Prefix and postfix operators in function calls [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I have seen in this site that prefix increment or postfix increment in a function call may cause undefined behavior. I have gone through one of those recently. The source code is something like this :
#include <stdio.h>
void call(int,int,int);
int main()
{
int a=10;
call(a,a++,++a);
printf("****%d %d %d***_\n",a,a++,++a);
return 0;
}
void call(int x,int y,int z)
{
printf("%d %d %d",x,y,z);
}
The output comes out as 12 11 12****14 13 14***_. But, when a is printed first in the function, shouldn't it be 10? Why does it become 12? Also, why does a++ decrease from 12 to 11? Can someone please kindly explain? Thank you.
There are two things your example code requires us to consider:
The function arguments order of evaluation is unspecified. Therefore, either ++a or a++ is evaluated first but it is implementation-dependent.
Modifying the value of a more than once without a sequence point in between the modifications is also undefined behavior.
Because of point 2, you have double undefined behavior here (you do it twice). Note undefined behavior doesn't mean nothing happens; it means anything can happen.
call(a,a++,++a); /* UB 1 */
printf("****%d %d %d***_\n",a,a++,++a); /* UB 2 */
That is undefined behaviour and as such it is entirely up to the implementation of the compiler in which order the following operations are done:
submit argument a
submit argument a++
submit argument ++a
increment a for ++a
increment a for a++
The only thing that the compiler knows is: 2. has to happen before 5. and 4. has to happen before 3.
You are observing:
++a;
submit argument 2
a++;
submit the other arguments
The C and C++ standards do not indicate an order of evaluation for function arguments. To be blunt, it is not incorrect for a compiler to cause the parameters to be evaluated from right to left, or left to right.
The best answer is, Stay Away from this type of 'Undefined Behavior'; as it can lead to subtle portability problems.
There's no requirement that a be equal to anything; that's what is meant by undefined behavior. It's entirely up to the compiler to evaluate the arguments to call and to printf in any order it sees fit, because the language does not specify what order they need to be evaluated.

Output of C program [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
int a[]={10,20,30,40};
int x=0;
int v=a[++x]+ ++x + a[--x];
printf("%d",v);
What will be the output of this program??
Completely confused with the output. No way it is going to be done according to my operator precedence knowledge.
According to me, in this expression Array subscripting [] has highest precendence and should be executed first. so both [] should be executed first from left to right. In this case value of x will increment first, then decrement and finally come back to 0. so expression will become int v=a[0] + ++x + a[0]. Then the pre increment is having highest precedence and it will be incremented to 1. so our expression will become int v=a[0]+1+a[0]. so final output will be 21.
But this is not the case. I have checked on different compiler implementations and no one prints 21.
I am much surprised because the value printed is 43, which is no where understandable to me. That's why I want someone to help me understand and come to the result 43.
The link which others have suggested is using only increment and same rvalue and lvalue cases. But this is somewhat different and not clear. I tried to contruct expression tree for this and solve but 43 is no where in scope.
Output of this code:
int v=a[++x]+ ++x + a[--x];
is undefined and it depends on the compiler implementation.

undefined behaviour in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Parameter evaluation order before a function calling in C
order of evaluation of function parameters
What will be the output of the following code:
n=5;
printf("%d %d\n", ++n, power(2, n));
output=32
shoulld not be the output be 2^6 =64?
will different compilers give different result?
Order of evaluation of function arguments is unspecified. The compiler can compute the arguments in any order it pleases, but it must do it in some particular order (so there's no undefined behaviour here). The output can be either 32 or 64.
UPD: this is wrong, there's UB here, see here.
Contrary to what other answers say, the code may indeed exhibit undefined behavior.
As has been stated, the order of evaluation of function arguments is unspecified in C. In your program, you have an expression composed of several subexpressions:
ex0(ex1, ex2, ex3(ex4, ex5));
There is only a partial ordering between these subexpressions: ex4 and ex5 must obviously be evaluated before ex3 can be evaluated, and ex1, ex2, and ex3 must be evaluated before ex0 can be evaluated. Other than that, the order of evaluation of the subexpressions is unspecified, and it is up to your compiler to decide the order in which to evaluate the subexpressions.
There are certain, valid orders of evaluations that yield undefined behavior. For example, if ++n is evaluated before power(2, n), the results are undefined: there is a sequence point after the evaluation of all of the arguments to a function but not before or between, and the C Language Standard very clearly states (C99 §6.5/2; emphasis mine):
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.
If ++n is evaluated first, this rule is violated because n is modified by ++n and n is read for the call to power(2, n) without a sequence point between those two steps.
A program that exhibits undefined behavior may produce any result: it may crash, it may print an unexpected answer, or it may appear to work as you expect it to work. Since your program potentially exhibits undefined behavior, it's difficult to discuss with certainty the actual behavior that you see. It is best to avoid writing programs that potentially (or worse, actually) exhibit undefined behavior.
And what does your power function contain? I just checked C math libraries pow function. I had to cast it to <int> like this;
#include <cstdio>
#include <cmath>
using namespace std;
int main () {
int n=5;
printf("%d %d\n", ++n, (int)pow(2.0, n));
return 0;
}
Output: 6 64
I used Microsoft Compiler(used by Visual Studio). Hope it helps.

Postfix and prefix operators as function arguments - why is this happening? [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I came across a very interesting fact while executing the following a simple c program:
#include<stdio.h>
int main( )
{
int k=0;
printf("%d%d%d", k++, k, ++k);
return 0;
}
in windows it was showing output as: 1 1 1
but in linux(ubuntu) it was showing as: 1 2 2
why is it so?
It's undefined behaviour. When there are no / ambiguous sequence points. See this wikipedia article:
http://en.wikipedia.org/wiki/Sequence_point
There are two problems. First is that the order in which the expressions k++, k, and ++k in the printf call are evaluated is not specified; the compiler is free to evaluate them in any order it sees fit. Second is that an object may not have its stored value updated more than once between sequence points by the evaluation of an expression. Both k++ and ++k attempt to update the value stored at k, and there is no sequence point between those expressions, so the behavior is undefined; any result is permitted.
The standard does not specify an ordering in which the arguments of a routine are evaluated.
Writing code that depends on the ordering is not portable.

Resources