Unable to understand the output of program in C - c

EDIT: This question is not duplicate as the behavior is not undefined in this case.
Why does the below program print the output as 231 in first line?
I have two doubts regarding this:
As I am doing postfix increment the value of x shouldn't have been increased before the I call max function. So the output should have been 1 in the first place instead of 2 according to me. What am I missing?
#define prn(a) printf("%d",a)
#define print(a,b,c) prn(a), prn(b), prn(c)
#define max(a,b) (a<b)? b:a
main()
{
int x=1, y=1;
print(max(x++,y),x,y);
printf("\n");
print(max(x++,y),x,y);
}
Output:
231
451
The postfix operation occurs after execution of the statement? Consider the example below.
int main()
{
int x = 0, y = 1;
int a = x++ /*x is incremented hereafter?*/+ y; // line 1
/* Or x is incremented now after execution of above line?*/ // line 2
int b = 0;
}

let me take this line
print(max(x++,y),x,y);
One important point to note is that the C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be inclusion of header file, macro expansions etc.
All preprocessing directives begins with a # symbol. For example,
#define PI 3.14
tells the compiler to replace the value PI with 3.14 where ever it sees.
c source code->preprocessor->compiler
therefore print(max(x++,y),x,y) is expanded in macro to
1. prn((x++<y) ? y:x++), prn(x), prn(y)
2. printf("%d",(x++<y)? y:x++), printf("%d",x), printf("%d",y);.
here it gets processed you can check two things carefully here
while checking
x++<y ,the x++ value is 1
then after that the x value becomes 2
so 2 is printed
and then while printing also we wrote x++ that means here x++ VALUE IS 2 but
after that x value is 3
so 3 is printed and it follows y as 1
that 's how it works
2.TO give you a great intuition on preincrement and post increment
let me take an example
int x=2;//value of x is 2
x++;//here x++ value is 2
after this line execution x value changed to 3
++x//here x++ value is 4 and also x value is 4.

Related

Why is the output different in these two scenarios

Please give me full description....
The first snippet of code has the 'function call' (macro invocation) before the increment operator, and second one has the function call after the increment operator.
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b)++;
printf("%d%d",a,b);
return 0;
}
output:
124
why is 124 returned here
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b++);
printf("%d%d",a,b);
return 0;
}
output:
125
and 125 here?
The thing to keep in mind is that macros provide simple substitution of preprocessor tokens. In particular, they may evaluate their arguments more than once, and if not guarded by parentheses, they may produce unintended reassociation.
In the first example, we have
a=square (b)++;
This expands to:
a=b*b++;
This is actually undefined behavior, since the b and b++ are unsequenced, and b++ modifies b. In your case, you are seeing 12 and 4 for a and b, so it would seem that the first value of b is picking up the incremented value, so you're getting 4*3, but you can't count on this behavior. The final value of b is 4 since it is incremented once.
In the second example, we have:
a=square (b++);
This expands to:
a=b++*b++;
This is again undefined behavior. In your case, it appears that you're getting 4*3 (or 3*4), but again, you can't count on this behavior. The final value of b is 5 since it is incremented twice, but this too is undefined behavior.
In addition to Tom's answer, which explains what is happening, here is an example of how you could define a macro for squaring a number safely:
#define SQR(x) ( \
{ \
__auto_type x_ = (x); \
\
x_ * x_; \
} \
)
It only has an appearance of x, and therefore it doesn't evaluate it twice. The copy x_ is used instead. Note that variables created in a macro may conflict with other variables created in the function that calls the macro. To avoid name collisions you use special names that shouldn't be used in normal code such as a trailing _.
With this macro, this:
a = SQR(b++);
will be equivalent to this:
a = SQR(b);
b++;
Warning: This works on some compilers as an extension (GCC for example), but it is not standard C.
Another option, if you want standard C, is to use an inline function. It is ok if you want it to work on just one type (there is _Generic in C11, but I never used it, so no idea).

What will be result of code execution? C Operator Precedence

I have a problem with predicting result of code linked below.
Why program is printing 2 0 6 0 10 0 16 0 20 0 ? I guess it is all about operators precedence, but after thinking a while I can't realize what's wrong with my interpretation. Can you explain it a little bit?
#include <stdio.h>
int main(void)
{
int tab[10] = {2,4,6,8,10,14,16,18,20};
int *pi, i;
for(pi = tab; ++pi < tab+9;)
{
*pi++ = 0;
*pi *= 2;
}
for(int i=0; i<10; i++)
printf("%d ", tab[i]);
return 0;
}
The first thing that the for loop does is point pi at tab, i.e. pi=&tab[0]
So pi is pointing at the number 2. The next piece of code to be executed is the for loop's "condition" statement ++pi < tab+9. This first increments pi (so it's now pointing at the number 4 in tab[1]) and checks whether it's still pointing at a member of tab earlier than the final 20.
In the body of the for loop, the line *pi++ = 0; first stores a 0 at the address pointed to by pi (which means that tab[1] is now 0 rather than 4) and then (post-) increments pi to point at tab[2], which is 6. Then the line *pi *= 2; doubles the value pointed to by pi, so tab[2] becomes 12.
The next thing that happens is a re-evaluation of the for loop's conditional statement (since its iteration statement is empty): pi is incremented and checked.
The rest of the iterations are fairly uneventful. The final state of tab is that the first member is unchanged, members with an odd index are zero, and other members are doubled from their initial value.
General advice regarding operators and precedence: one of two situations is almost always the case. The first is that you and the compiler don't agree on the order in which the operators in your code will be applied—in other words your code doesn't do what you expect. The second is that you understand perfectly what the compiler is going to do, but the programmer reading your code does not—in other words your code doesn't do what they expect. Fortunately, both situations can be mitigated by adding parentheses to remove any doubt.
The actual output is 2 0 12 0 20 0 32 0 40 0 (as shown in Blastfurnace comment https://ideone.com/UUy8QO)
pi is indeed initially on the first cell, but your stop condition increment the pointer. Therefore, inside the loop, for the first instruction, pi is in tab[1]. It first put this cell to 0, then increment with ++. On the second line, it double the value, therefore it double tab[2]. Then, the stop condition again increment the pointer, and so on.

Unexpected output printf statement [duplicate]

This question already has answers here:
Why is "i" variable getting incremented twice in my program?
(8 answers)
Closed 7 years ago.
Why outputs of i and j in the following two printf()s are different?
#include <cstdio>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
int i=10,j=5,k=0;
k==MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
i=10,j=5,k=0;
k=MAX(i++,++j);
printf("%d %d %d\n",i,j,k);
return 0;
}
I think only k should differ, but it is showing different output for all, i, j and k, in printf() statement. What is the reason?
Output :
11 7 0
12 6 11
k==MAX(i++,++j); is translated to:
k==(i++) > (++j) ? (i++) : (++j);
/* 2 1 3 : Precedance */
In your case i = 10 and j = 5, so the comparision would be 10 v/s 6 which would be true or 1 with side effect i becomes 11 and j becomes 6. (Recall that: Macros are not functions)
As k = 0 and not equal to 1, k==(i++) > (++j) would be false and ++j would be executed. Causing j to be incremented to 7.
In latter case, there is no modification to the value of variables.
When can I expect same output in both case?
Even if you change the macro with a function, your arguments have the side effects, which would cause the output 11 6 for i j, so you are changing the variables using ++ operator, don't expect both statements to have the same values.
i++ and ++j both increment i and j, so you change their values before printing.
You have side-effects.
MAX(i++,++j)
is expanded to
(i++)>(j++)?(i++):(j++)
And i is modified twice in the macro call.
Moreover, you have to add parens to your macro definition:
#define MAX(x,y) ((x)>(y)?(x):(y))
Let's analyse the output from first printf()
Assuming you meant = instead of == in your code,
k==MAX(i++,++j);
gets translated to
k = (i++) > (++j) ? (i++): (++j)
which gets evaluated changing all the values of i, j and k.
Even if you meant ==, as mentioned in the answer by Mr. Mohit Jain, you'll face similar issue with precedence.
Have a look at operator precedence for better understanding.
Let's analyse the output from second printf()
In the second printf() statement, you're re-setting the values of i, j, k and not using the MACRO. So, those values will get printed. Simple.
So, TL;DR, before first printf(), the MACRO changes all the three values for i, j, k. So, your output for first and second printf() differs for all the three variable values.
FWIW, if you meant the MACRO to behave as a ternary conditional expression , you need to change your MACRO definition to
#define MAX(x,y) ( (x)>(y) ? (x) : (y) )
To avoid issues with operator precedence after MACRO expansion.
The macro is a red herring. OP did not ask about k but "Why output of i and j in following two printf are different?" The answer is because i and j have been modified between setting their values and printing, in the first case, but not in the second case.

task in increment , decrement , printf() , why these are evaluated in this manner in C [duplicate]

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>
#include<stdlib.h>
int main() {
int a=3;
//case 1
printf("%d %d %d\n",(--a),(a--),(--a));//output is 0 2 0
printf("%d\n",a);//here the final value of 'a'
//end of case 1
a=3;
//case 2
printf("%d\n",(++a)+(a--)-(--a));//output is 5 value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 2
a=3;
//case 3
printf("%d\n",(++a)*(a--)*(--a));//output is 48 value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 3
//case 4
int i=3,j;
i= ++i * i++ * ++i;
printf("%d\n",i);//output is 81
i=3;
j= ++i * i++ * ++i;
printf("%d\n",j);//output is 80
//end of case 4
return 0;
}
I am clear with how these outputs are coming as I spent nearly 3 hours in it gazing at it , but all I want to know in detail is that why it is being taken or evaluated in this manner.
This was tricky one to judge printf evaluates from right to left so first
--a pushes 2 , next a-- pushes 2 again as it is post then a becomes 1 , then --a makes first a 0 and then pushes that to and all i guessed that the output would be 0 2 2 but to my surprise it was 0 2 0 then i get it that the final value of a=0 is given to all the places where i used pre increment and decrement . Why this happens ?
This i take it as normal evaluation and then printing a is made 4 then in a-- again a is taken as 4 and again in --a a is taken as 3 so 4+4-3=5 done then final value of a happens to be one -1 from the post decrement that was done in the middle so a becomes 2 again Why this is happening ?
This execution is same as above and takes 4 * 4 * 3 = 48 and final a value is 2.
This is not tricky but i want the answer to it in detail what i figured is that first i becomes 4 in ++i and at i++ i becomes 4 and then at ++i i becomes 5 and so then 4*4*5 = 80 in this case i store it in i itself and then so i becomes 80 and then one +1 for the post increment. So i can one clear decision when i store 80 in another variable j and then saw it was 80 and the final i value was 6.
So logically I judged from just printing and viewing things in all these cases and are yet more which are completely based in this to come i can go on posting SO WHAT I WANT IS THAT AT ASSEMBLY LEVEL HOW IT IS HAPPENING AND WHY like IT TAKES POST INCREMENT AS A SEPARATE STATE OR SOMETHING how can different programs like this can be judged generically for each i cannot keep printing and finding the pattern can somebody help me in detail here. And the worst part was that i just executed the code in ideone and gives me completely different output you can even test at ideone if you are interested so why these happens please someone tell me i am breaking my head at this thing for 3 hours help me professionals.And i used gcc compiler.
This is all undefined behavior modifying a variable more than one in between sequence points in this in this case within the same expression is not allowed. So you can not rely on the output of this program at all.
From the c99 draft 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.
it cites the following code examples as being undefined:
i = ++i + 1;
a[i++] = i;

Using Nested macros in C

#include "stdafx.h"
#include<stdio.h>
#define PR(x) printf("%d\t",(int)(x));
#define PRINT(a,b,c) PR(a) PR(b) PR(c)
#define MAX(a,b) (a<b?b:a)
int main()
{
int x=1,y=2;
//PR(MAX(x++,y));
PRINT(MAX(x++,y),x,y); //2,2,2
PRINT(MAX(x++,y),x,y); //2,3,2
return 0;
}
x is 1 so the 3 values to be passed as arguments in PRINT is 2 2 2.
Then in the second PRINT the values that will be passed is 2 3 2. So the output should be 2 2 2 2 3 2. But this program outputs as 2 2 2 3 4 2.
Your MAX macro is bad. It evaluates one of its arguments twice.
MAX(x++,y)
expands to:
(x++ < y ? y : x++)
^^^
So x is incremented twice if it started out smaller than y.
There is no undefined behavior in that code because there is a sequence point between the evaluation of the first part of the ternary operator and the part that is selected. The whole PRINT expression expands to:
printf("%d\t", (x++ < y ? y : x++));
printf("%d\t", (x));
printf("%d\t", (y));
Which is all fine. This does not mean you should be using such macros. Use simple functions, and let the compiler do its job of type-checking and inlining what it thinks is best.
Your macros have several problems:
Never hide a ; inside a macro but have it behave like an ordinary
statement
Don't write macros that evaluate their arguments multiple times
always put parentheses around macro parameters such that you know the
precedence of all operators.
Your MAX(x++,y) call translates to (x++<y?y:x++) and results in double modification of x during the first call.
PRINT((MAX(x++,y),x,y) -> PR(MAX(x++,y)) PR(x) PR(y) -> PR(x++
x = 1, y = 2
Does PR(2 since 1<2) and increments x to 2
Then PR(2) PR(2) - Hence output 2 2 2
Next PR(MAX(x++ (i.e.2) < 2 - false) ? 2 : x++ (i.e use incremented value of x from condition (3) then output 3 and increment x to 4) - hence x gets incremented twice

Resources