#define directive in C Giving ambiguous answer [duplicate] - c

This question already has answers here:
C : #define usage [duplicate]
(3 answers)
Closed 7 years ago.
#include <stdio.h>
#define SQR(x) x*x
int main()
{
printf("%d",225/SQR(15));
return 0;
}
The output to this code is 225. I'm unable to understand as what really is happening here.
If I use #define SQR(x) (x*x) Then it works fine which i get as we are supposed to use parentheses if we have an expression with some operator.
But in the previous case I'm not clear as to what is really happening. Why is the answer 225?

#define macros aren't functions - they are just macros, text replacement. If you take the expression 225/SQR(15) and replace SQR with 15*15, you'll get 225/15*15, and since / and * have the save precedence and are left associative - 255/15*15 = 255.

Macros do substitution only(done before compilation of the code).
Therefore the following line
printf("%d",225/SQR(15));
after substitution will become:
printf("%d",225/15*15);
now this expression evaluates to 225 (basic maths : divide first -> 15*15, then multiply -> 225)
using brackets solves your problem(then it becomes 225/(15*15)).
:)

Notice the steps
1) 225/SQR(15)
2) 225/15*15
Division executed first due to precedence
3) 15*15
4) 225

See #define as a text replacement tool in a text editor; it works the same way (well, almost).
Here are two rules you might want to follow in order to avoid this kind of errors:
When working with macros, always use parentheses for each "variable" given to the macro and for the whole result.
Example:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
When you have an unexpected behavior, use the command line tool cpp (c preprocessor) to see how the macro is actually interpreted.
Example:
$ cpp main.c

Related

How ## operator in macro works?

I was studying some macro operations, and I got this Code and I was unable to figure out how this code is actually working and generates the output? and is there any (i-+) operator that exists or not?
Here is the code
#include<stdio.h>
#define p(a,b) a##b
#define call(x) #x
int main()
{
do{ int i=14,j=3;
printf("%d",p(i-+,+j));
}while(*(call(625)+3));
return 0;
}
Output is 10.
It will be very helpful if you explain it with some examples.
The ## in the macro is the concatenation operator, it glues its operands together. So after the preprocessor is done, that expression will be
i-++j
which of course just means i - (++j), i.e. 14 - 4 which of course is 10.

Bad parentheses in macro definition

I was reading this tutorial of stanford where they say :
Common coding mistakes:
Bad parentheses in macro definition
#define min(a, b) a<b?a:b // incorrect
#define min(a, b) (((a)<(b))?(a):(b)) // correct
I even ran this in a program, It worked fine.
Can anybody explain what they are trying to say!
The first version fails if you combine it with other operators:
min(a , b) + c
and translates to:
a<b?a:b+c
which is identical to:
a<b?a:(b+c)
which is an unexpected outcome given the starting parenthesis.
The second version isn't much better. It evaluates one of the parameters twice which can cause unexpected behavior if a function or i++ is passed to the macro.
An inline function should be used instead of those macros.

How to force processor to use result of expression before pasting

My code is
#define PASTE__(a, b) a##b
#define PASTE_(a, b) PASTE__(a, b)
#define PASTE(a, b) PASTE_(a, b)
int main()
{
PASTE(1, (1+3)/4);
return 0;
}
I would LIKE to have the result be
int main()
{
11;
return 0;
}
Compilable link: http://coliru.stacked-crooked.com/a/b35ea3e35a1b56ae
I put in two levels of indirection suggested by How can I guarantee full macro expansion of a parameter before paste?.
But still I get a preprocessor error:
main.c:8:11: error: pasting "1" and "(" does not give a valid preprocessing token
PASTE(1, (1+3)/4);
^
main.c:1:23: note: in definition of macro 'PASTE__'
#define PASTE__(a, b) a##b
^
main.c:3:21: note: in expansion of macro 'PASTE_'
#define PASTE(a, b) PASTE_(a, b)
^
main.c:8:5: note: in expansion of macro 'PASTE'
PASTE(1, (1+3)/4);
How do I get the preprocessor to resolve the result of that expression before doing concatenation?
It looks like you're trying to get the preprocessor to evaluate some simple mathematical operations and convert to the result. This is not possible without substantial extra macro infrastructure to perform the necessary math. The easiest way to get the needed infrastructure is probably to use BOOST_PP.
http://www.boost.org/doc/libs/1_59_0/libs/preprocessor/doc/index.html
You would need to modify your code so that macros are used to perform the math rather than operators. The line in question would look like:
PASTE(1, BOOST_PP_DIV(BOOST_PP_ADD(1,3),4));
Now the answer would come out as 11, and I assume that's what you're looking for.
What exactly are you hoping the preprocessor output for the PASTE line will be? 11;? That's impossible. (update: apparently it is possible with clever enough macros. See Charles Ofria's answer).
That double-expansion with multiple macros is only useful for expanding macros and then stringifying the results, IIRC.

macro arguments

What will the program print when the inputs are 2,3?
#include <stdio.h>
#define min(a,b) ((a) > (b) ? (b) : (a))
#define inc(a) a++
#define mult(a,b) (a * b)
int main(void) {
int x = 1, y = 2;
scanf("%d %d",&x,&y);
printf("min(%d,inc(%d))",x,y);
printf("=%d\n",min(x,inc(y)));
printf("min(mult(%d,%d+2),11)",x,y);
printf("=%d\n",min(mult(x,y+2),11));
return 0;
}
edit: I get funny answer for negative numbers i.e -1,-2.
Why is inc(-2) change y to zero instead of -1?
Think of a macro as simply string replacement. Just replace the macro name and parentheses with the body of the macro definition, replacing the macro parameters with what is passed in. An example is easier:
#define hello(a) a+a
...
int y = hello(x);
Would be replaced with:
int y = x+x;
To answer your question, do this manually, and very, very carefully. For nested macros, start with the inside one. Did I mention do this carefully? Don't add or remove any sets of parentheses.
The output would be:
min(2,inc(3))=2
min(mult(2,4+2),11)=11
What do you mean with overwrite?
If you define a function like you did above and call for example this:
inc(x);
.. then the compiler turns it into x++. The variable a is just a name for the "paramter" and will also be replaced by the real variable.
What operating system are you running? you can easily run this yourself and see the results
if your on Windows I would suggest getting CodeBlocks or Visual Studios
if your on Linux or MAC , learn to compile from terminal using gcc or g++

Why can't I use sizeof() in a #if? [duplicate]

This question already has answers here:
Why can't I use sizeof in a preprocessor condition?
(2 answers)
Closed 9 years ago.
I have this:
#if sizeof(int)
#error Can't use sizeof in a #if
#endif
I get this compiler error:
missing binary operator before token "("
Why can't I use the sizeof operator here?
Because sizeof() is calculated after the preprocessor is run, so the information is not available for #if.
C compilers are logically split into two phases, even if most modern compilers don't separate them. First, the source is preprocessed. This involves working out and substituting all the preprocessor conditionals (#if, #define, replacing defined words with their replacements). The source is then passed, processed, to the compiler itself. The preprocessor is only minimally aware of the structure of C, it has no type knowledge, so it can't handle compiler-level constructs like sizeof().
Because you can only use literal constants in a preprocessor directive. Besides, sizeof(int) is always larger than 0, so I believe this #if would be true all the time anyway.
Consider:
#if sizeof(MyClass) > 3
#define MY_CONSTRAINT 2
#endif
class MyClass
{
#if MY_CONSTRAINT == 3
int myMember = 3;
#endif
};
Now, this is prolly not written in the correct syntax as it's been a while since the last time I did C++, but the point still stands :)
just use ordinary if-else
if (sizeof(x)==2) {...}
else if (sizeof(x)==4) {...}
else {...}
and compiler will optimize it in compile time...

Resources