#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
Related
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.
Why am I getting the answer "odd" instead of "even"?
#include<stdio.h>
#define ODD(x) x%2?0:1
int main()
{
int a=5;
if(ODD(a+1))
printf("even");
else
printf("odd");
return 0;
}
ODD(a+1) expands to a+1%2?0:1. With a as 5, that is same as (5+(1%2))?0:1 or 0.
% beats + which beats ?:
if(0)
printf("even");
else
printf("odd"); // print `odd`
Perhaps you wanted some () to insure evaluation order.
// #define ODD(x) x%2?0:1
#define ODD(x) ((x)%2?0:1)
Yet that seems backwards. How about
#define ISODD(x) ((x)%2 != 0)
See How do I check if an integer is even or odd?
1 is treated as true and 0 as false.
if (1) is executed always, and when you get 0 as result, the branch shifts to else
so code should be :
if ODD is true (returning 1 from terneray expression), print "odd"
#define ODD(x) x % 2 ? 0 : 1
Given an even number x, x % 2 will give you zero, which is false.
Hence the result of the entire ternary expression will be the second option 1, which is true.
You would be better off with something like:
#define ODD(x) (((x) % 2) != 0)
It's both more readable in intent, and less prone to errors such as getting the true/false values mixed up, or being burnt by simple text substitution having unexpected effects.
I do not like this kind if macros for many reasons (one of it that they can be a source of silly errors - like in your case). It should be domain of functions.
int ODD(int x)
{
return x & 1;
}
if you are worried about function call overhead just make it inline (but on any level op optimisation the compiler will inline it anyway as the call is probably longer than the function itself.
I have come across a piece of code. I am wondering why is the below code returning the value of x as four and not zero.
if(2<1);
else x = (2<0) ? printf("one") : printf("four");
printf("%d",x);
output is 4
Please instead of trying to read the unreadable, make it readable and enjoy
if (2 < 1);
else
x = (2 < 0) ? printf("one") : printf("four");
printf("%d", x);
Of course 2 < 1 is false, and 2 < 0 is false again so the return value of printf("four") which is 4 because "four" has 4 characters is assigned to "x".
So the output should be
four4
Function printf returns the number of printed characters.
Because in this conditional operator
(2<0)?printf("one"):printf("four")
the condition (2<0) is false this expression printf("four") is evaluated and its value is equal to 4 - the number of the outputed characters.
From the description of function printf (the C Standard, 7.21.6.3 The printf function)
3 The printf function returns the number of characters
transmitted, or a negative value if an output or encoding error
occurred.
I think that the reason of the confusion is the assignment operator before the
conditional operator. However the assignment operator has lower priority compared with the conditional operator. So in fact you have
else x = ( (2<0) ? printf("one") : printf("four") );
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.
Why does the following code report an Lvalue required error?? And how can we write a macro that receives an array and the number of elements in the array as arguments and then print out the elements of the array??
#define arr(b) printf("%d",b++);\
printf("%d",b);
int main()
{
arr(5);
}
If you expand the macro, you get the following:
int main()
{
printf("%d",5++);
printf("%d",5);
}
You cannot postincrement the constant 5, so you get an error.
Remember, macros aren't functions. If you want it to act like a function, simply make a function:
void arr(int b) {
printf("%d",b++);
printf("%d",b);
}
Because part of that macro expands to 5++, which is not valid C. Consider using b+1 instead of b++.
The first l in lvalue stands for left.
Only left values can be assigned.
when you write x ++ you mean x = x + 1 (also you get a value from it).
So the problem is it does not make sense to write 5 = 5 + 1
maybe you would like to do this:
int x = 5;
arr(x);