Behaviour of macro changes when used with parenthesis - c

Why is max(0,1) behaving differently than max(1,0) in this program?
#define max(a,b) ((a)>(b))?(a):(b)
int main()
{
printf("max(0,1) = %d \n",max(0,1));
printf("max(0,1)+1 = %d \n",max(0,1)+1);
printf("max(0,1)+2 = %d \n",max(0,1)+2);
printf("max(1,0) = %d \n",max(1,0));
printf("max(1,0)+1 = %d \n",(max(1,0)+1));
printf("max(1,0)+2 = %d \n",(max(1,0)+2));
return 0;
}
output:
max(0,1) = 1
max(0,1)+1 = 2
max(0,1)+2 = 3
max(0,1) = 1
max(1,0)+1= 1
max(1,0)+2= 1
And why do these behave well if one extra parenthesis is used?
#define max(a,b) (((a)>(b))?(a):(b))

Because the ?: conditional operator has lower operator precedence than the binary + operator.
Thus max(1,0)+1 gets interpreted as 1>0?1:(0+1)
Perfect example of why you shouldn't use function-like macros.

The ternary operator ? : has a very low operator precedence: much lower than addition. Therefore you need to put the ternary in brackets so, when it's used to compute a maximum, the final addition, if any, is computed after the ternary.
You can always resort to unpicking a macro:
max(1,0) + 1 unpicks, with your first definition of max to (1) > (0) ? (1) : (0) + 1 which is, of course, 1. With the second definition it is ((1) > (0) ? (1) : (0)) + 1 which is 2.

After the macro expansion #define max(a,b) ((a)>(b))?(a):(b), your statements
printf("max(0,1)+1 = %d \n",max(0,1)+1);
printf("max(1,0)+1 = %d \n",(max(1,0)+1));
looks like
printf("max(0,1)+1 = %d \n",0 > 1 ? 0: (1+1));
printf("max(1,0)+1 = %d \n",(1 > 0 ? 1: (0+1)));

Related

Whats the logic behind the output [duplicate]

I was just going through certain code which are frequently asked in interviews. I came up with certain questions, if anyone can help me regarding this?
I am totally confused on this now,
#include <stdio.h>
#include <conio.h>
#define square(x) x*x
main()
{
int i, j;
i = 4/square(4);
j = 64/square(4);
printf("\n %d", i);
printf("\n %d", j);
printf("\n %d", square(4));
getch();
}
The output is:
4
64
16
I am wondering, why did square(4) return 1 when I divided it? I mean, how can I get the value 4 and 64 when I divide it, but when used directly I get 16!!?
square is under-parenthesized: it expands textually, so
#define square(x) x*x
...
i=4/square(4);
means
i=4/4*4;
which groups as (4/4) * 4. To fix, add parentheses:
#define square(x) ((x)*(x))
Still a very iffy #define as it evaluates x twice, so square(somefun()) calls the function twice and does not therefore necessarily compute a square but rather the product of the two successive calls, of course;-).
When you write i=4/square(4), the preprocessor expands that to i = 4 / 4 * 4.
Because C groups operations from left to right, the compiler interprets that as i = (4 / 4) * 4, which is equivalent to 1 * 4.
You need to add parentheses, like this:
#define square(x) ((x)*(x))
This way, i=4/square(4) turns into i = 4 / ((4) * (4)).
You need the additional parentheses around x in case you write square(1 + 1), which would otherwise turn into 1 + 1 * 1 + 1, which is evaluated as 1 + (1 * 1) + 1, or 3.
i=4/square(4);
expands to
i=4/4*4;
which equivalent to
i=(4/4)*4;
Operator precedence is hurting you.
The macro is expanded by the pre-processor such that
i=4/4*4;
j=64/4*4;
which is equivalent to:
i=(4/4)*4;
j=(64/4)*4;
That's because the compiler replaces it with:
i=4/4*4;
j=64/4*4;
i = (4/4)*4 = 1*4 = 4.
j = (64/4)*4 = 16*4 = 64.
j = 4/square(4) == 4/4*4 == 1*4 == 4
Manually expand the macro in the code, and it will be clear. That is, replace all the square(x) with exactly x*x, in particular don't add any parentheses.
define is just a text macro
main()
{
int i,j;
i=4/ 4 * 4; // 1 * 4
j=64/4 * 4; // 16 * 4
printf("\n %d",i);
printf("\n %d",j);
printf("\n %d",square(4));
getch();
}
It's a macro! So it returns exactly what it substitutes.
i = 4/4*4; Which is 4...
j = 64/4*4; Which is 16...
Try this for your macro:
#define square(x) ((x)*(x))
Because of operator precedence in the expression after the preprocessor - you'll need to write
#define square(x) (x*x)
As the other answers say, you're getting burned by operator precedence. Change your square macro to this:
#define square(x) (x*x)
and it'll work the way you expect.

How do I put a function inside a macro? [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Unintended multiple evaluation of parameter in macro
(1 answer)
Closed 6 years ago.
#include <stdio.h>
// 2.1
#define subm(a,b) (a - b)
#define cubem(a) (a * a * a)
#define minm minf
#define oddm oddf
//---------------------------Given Code------------------------------------
int subf(int a, int b) {
return a - b;
}
int cubef(int a) {
return a * a * a;
}
int minf(int a, int b) {
if (a <= b) {
return a;
} else {
return b;
}
}
int oddf(int a) {
if (a % 2 == 0) {
return 0;
} else {
return 1;
}
}
//----------------------------Given Code----------------------------------
// 2.2
int main() {
int a = 5;
int b = 7;
subf(a,b);printf("subf = %d\n", subf(a,b));
subm(a,b);printf("subm = %d\n", subm(a,b));
subf(a++,b--);printf("subf = %d\n", subf(a++,b--));
subm(a++,b--);printf("subm = %d\n", subm(a++,b--));
cubef(a);printf("cubef = %d\n", cubef(a));
cubem(a);printf("cubem = %d\n", cubem(a));
cubef(--a);printf("cubef = %d\n", cubef(--a));
cubem(--a);printf("cubem = %d\n", cubem(--a));
minf(a,b);printf("minf = %d\n", minf(a,b));
minm(a,b);printf("minm = %d\n", minm(a,b));
minf(--a,--b);printf("minf = %d\n", minf(--a,--b));
minm(--a,--b);printf("minm = %d\n", minm(--a,--b));
oddf(a);printf("oddf = %d\n", oddf(a));
oddm(a);printf("oddm = %d\n", oddm(a));
oddf(a++);printf("oddf = %d\n", oddf(a++));
oddm(a++);printf("oddm = %d\n", oddm(a++));
}
I'm having some trouble with putting the functions inside the macro. My professor wants us to understand how macro and functions are processed. The way I'm doing it is basically as you see here, but it's not working correctly, or at least
#define cubem(a) (a * a * a)
Is generating an error and I don't know why. Can someone please help?
edit: the error is as shown
hw02q2.c:42:31: warning: multiple unsequenced modifications to 'a'
[-Wunsequenced]
printf("cubem = %d\n", cubem(--a));
^~
hw02q2.c:4:19: note: expanded from macro 'cubem'
#define cubem(a) (a * a * a)
The reason is that
#define cubem(a) (a * a * a)
/* and later using it .... */
printf("cubem = %d\n", cubem(--a));
does text substitution, and produces
printf("cubem = %d\n", (--a * --a * --a));
which modifies a three times in one statement. That is undefined behaviour according to the C standard.
In comparison,
int cubef(int a) {
return a * a * a;
}
/* and later */
printf("cubef = %d\n", cubef(--a));
evaluates --a once, passes the resultant value to cubef().
If you really want to "put a function in a macro", then do something like
#define cubem(a) cubef(a)
which causes the statement
printf("cubem = %d\n", cubem(--a));
to become
printf("cubem = %d\n", cubef(--a));
The problem with this is that it does not work with a macro that uses its argument more than once. For example
int sq(int a) {return a * a;}
#define cubesq(a) (a * sq(a)) /* uses a more than once
causes
printf("cubesq = %d\n", cubesq(--a));
to be seen by the compiler as
printf("cubem = %d\n", (--a * cubesq(--a));
which, again, modifies a more once and causes undefined behaviour.
The reason is simple: the preprocessor does TEXT SUBSTITUTION and modifies source code seen by a later phase of the compiler.
Instead of "trying to put a function inside a macro", simply don't use macros. Write functions. Use functions. Or use macros, but respect their limitations (i.e. they don't work like functions do, even if they look like functions).
C Macros perform textual substitution: each instance is replaced with the macro definition with the macro parameter names replaced with the exact text of the instance arguments.
Your cubem macro defined as #define cubem(a) (a * a * a) will expand this way:
cubem(--a) -> (--a * --a * --a)
Modifying a multiple times within the same expression has undefined behavior. You cannot work around this problem portably. You could try using compiler extensions if you are familiar enough and don't mind relying on non-portable constructions.
The correct way to implement the function and have it expand inline is via an inline function definition:
static inline cubem(int a) { return a * a * a; }
Note also that the macro has other problems:
cubem(1 + 1) expands to (1 + 1 * 1 + 1 * 1 + 1) which evaluates to 4 instead of 8.
To avoid this problem, all macro arguments should be parenthesized:
#define cubem(a) ((a) * (a) * (a))
But this definition still does not support arguments with side effects:
cubem(getchar()) will read 3 bytes from standard input.
Since you invoke cubem(--a) like this, your cubem definition should avoid side effect.
#define cubem(a) \
({ \
typeof(a) dummy_a = (a); \
dummy_a * dummy_a * dummy_a; \
})
Above is a gcc c extension, read the gcc document, chapter
Statements and Declarations in Expressions

Shorthand Way of Conditional Assignments

Is there a shorthand way of writing equivalent code to:
if (variable > max){
variable = max;
}else if (variable < -max){
variable = -max;
}
I know I can use ternary operators to get code like this:
variable = variable > max ? max : variable;
variable = variable < -max ? -max : variable;
Question:
But is there an even shorter version of this code?
Note: Not nested ternary operators, either.
P.S.: This isn't necessarily a language-specific question, but I'm writing my code in C so I'd like to have answers that can work in that language.
You could probably use this construct:
if (abs(variable) > max) {
variable = sgn(variable) * max;
}
There is no sgn(x) function in standard C library, but it is easy enough to implement it using arithmetic operations:
#define sgn(x) (((x) > 0) - ((x) < 0))
Here is an working example:
#include <stdio.h>
#include <math.h>
#define sgn(x) (((x) > 0) - ((x) < 0))
int main(void)
{
int variable = -100, max = 20;
if (abs(variable) > max) {
variable = sgn(variable) * max;
}
printf("%d\n", variable);
return 0;
}
Note, that it will not work for INT_MIN on systems, that use two's complement representation, because -INT_MIN cannot be represented as int (kudos for #M.M).
You can nest conditional operators:
variable = variable > max ? max : (variable < -max ? -max : variable);
IMHO this is almost unreadable, so I don't recommend it.

How does the preprocessor work in C?

Why is the answer for the below code 16? Can anybody explain the working of this program?
#define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
If we write the same code like below, then the answer is 4:
//the ans is 4 why?
#include<stdio.h>
#include<conio.h>
#define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
The preprocessor just replaces the text, exactly as written.
So, the macro call SQUARE(2) becomes literally 2*2.
In your case, that means the whole expression becomes 16/2*2, which because of C's precedence rules evaluates to (16/2)*2, i.e. 16.
Macros should always be enclosed in parenthesis, and have each argument enclosed as well.
If we do that, we get:
#define SQUARE(n) ((n) * (n))
which replaces to 16/((2) * (2)), which evaluates as 16/4, i.e. 4.
The parens around each argument makes things like SQUARE(1+1) work as expected, without them a call such as 16/SQUARE(1+1) would become 16/(1+1*1+1) which is 16/3, i.e. not at all what you'd want.
Order of operations. Your expression is evaluating to:
j = 16 / 2 * 2
which equals 16. Make it:
#define SQUARE(n) (n*n)
which will force the square to be evaluated first.
You need to define your macro with insulating parentheses, like so:
#define SQUARE(n) ((n)*(n))
Otherwise
j = 16/SQUARE(2);
expands to
j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2
When what you want is
j = 16 / (2 * 2);
1. When using macros that are to be used as expressions, you should parenthesise the whole macro body.
This prevents erroneous expansions like:
#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5
2. If the macro arguments are expreessions, you should parenthesise them too.
This prevents a different type of problems:
#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2
Hence the correct way is to write it like this:
#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))
Using macros as functions is discouraged though (guess why), so use a function instead. For instance:
inline double square(n) { return n*n; }
The Expansion of macro will be like:
j = 16/SQUARE(2);
j = 16/2*2;
Which is equal to : j = (16/2)*2; Means j = 16;
and :
j = 16/(SQUARE(2));
j = 16/(2*2);
Which is equal to : j = 16/4; Means j = 4;
Because the macro will be expanded as:
j = 16/2*2;
The pre-compiler does not do any processing on the expansion. It places the expanded macro in your code as it is. Since you have not parenthesized the replacement text it wont do it for you in the main code as well. Make it :
#define SQUARE(n) ((n)*(n))
The first example is evaluated as:
16 / 2 * 2
(16 / 2) * 2
8 * 2
16
The second example is evaluated as:
16 / (2 * 2)
16 / 4
4
Add parenthesis to you preprocessor statement to control the order of operations:
#define SQUARE(n) ((n)*(n))
The outer parenthesis in ((n)*(n)) ensure that n is squared before any outside operation is performed. The inner parenthesis (n) ensure that n is correctly evaluated in cases where you pass an expression to SQUARE like so:
16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1
you'll get
j =16/2*2; // (16 / 2) * 2 = 16
Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro.
Case 1 : result 16
define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/SQUARE(2);
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/2*2
j = (16/2)*2
j = 8*2
j =16
Case 2 : result 4
define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/(SQUARE(2));
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/(2*2)
j = 16/(4)
j = 4
Hope this will help

Can int return-type function return true?

Here is the program that I am trying to compile
#include<stdio.h>
int main()
{
int i = 0;
rec(i);
}
int rec(int i)
{
i = i + 1;
if (i == 10){return true;}
rec(i);
printf("i: %d\n", i);
}
I am getting this output
$ gcc -o one one.c
one.c: In function ‘rec’:
one.c:10:24: error: ‘true’ undeclared (first use in this function)
one.c:10:24: note: each undeclared identifier is reported only once for each function it appears in
As far I believe is Boolean true evaluates to 1 in c. If so why am I getting an error?
There are no true or false keywords in C. There are some library definitions for those values in stdbool.h (starting in C99, I think) but oft times most C programmers will just use 1 and 0.
If you don't want to use stdbool.h, or you're working on a compiler that doesn't support it, you can usually define the constants yourself with something like:
#define FALSE (1==0)
#define TRUE (1==1)
or you can use 1 and 0 directly - the method above is for those who don't want to have to remember which integer values apply to which truth values (a).
0 is false, any other value is true. So your code would look something like (fixing up the return value problem as well though I'm not sure why that's even there since it always returns true.):
#include <stdio.h>
int rec (int i) {
i = i + 1;
if (i == 10)
return 1;
printf ("i: %d\n", i);
return rec (i);
}
int main (void) {
int rv, i = 0;
rv = rec (i);
printf ("rv: %d\n", rv);
return 0;
}
which gives you:
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
rv: 1
I should also mention that recursion is a solution best used when the search space is reduced quickly, such as in a binary tree search where the search spaces halves on each recursive call. It's not usually a good fit for something where you just increment a value on each call although, in this case, it's probably okay since you limit it to about ten levels.
(a): Keep in mind the caveat that, although the given definition of TRUE will most be 1, any non-zero value will be treated so. That means that the two statements:
if (isValid)
if (isValid == TRUE)
do not mean the same thing. There are a large number of possible isValid values which will be pass the first test but fail the second. That's usually not a problem since it's almost always a bad idea to compare boolean variables with boolean constants anyway.
If you want to use true/false, you can put your compiler in C99 mode (std=c99 for GCC) (or C11), and include <stdbool.h>.
(Or you'll need to define true and false using preprocessor directives or global constants.)
You can put a simple 'if' statement in it
#include<stdio.h>
int main()
{
int i = 0;
rec(i);
}
int rec(int i)
{
i = i + 1;
if (i == 10){
return 1;
}
j = rec(i)
if (j == 1){
printf('true')
}
printf("i: %d\n", i);
}
c does not have a boolean proper. You could have a define for it though
#define true 1
#define false 0
If your C doesn't use the C99 standard, then there is neither true nor false. When designing a function that returns a boolean, i.e.
short isOdd(long);
I would use 1 and 0 to represent true and false respectively. This is ok because if you try the following snippet with i=1 (or any non-zero ints), it prints T; with i=0, it prints F.
if (i)
putch('T');
else
putch('F');
Here's the example of an function that tests if a number is odd:
short isOdd(long num)
{
return num%2; // evals to 1 if num is odd; 0 otherwise
}
Hope that helps.

Resources