This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 5 years ago.
I tried to play with the definition of the macro SQR in the following code:
#define SQR(x) (x*x)
int main()
{
int a, b=3;
a = SQR(b+5); // Ideally should be replaced with (3+5*5+3), though not sure.
printf("%d\n",a);
return 0;
}
It prints 23. If I change the macro definition to SQR(x) ((x)*(x)) then the output is as expected, 64. I know that a call to a macro in C replaces the call with the definition of the macro, but I still can’t understand, how it calculated 23.
Pre-processor macros perform text-replacement before the code is compiled so
SQR(b+5) translates to
(b+5*b+5) = (6b+5) = 6*3+5 = 23
Regular function calls would calculate the value of the parameter (b+3) before passing it to the function, but since a macro is pre-compiled replacement, the algebraic order of operations becomes very important.
Consider the macro replacement using this macro:
#define SQR(x) (x*x)
Using b+5 as the argument. Do the replacement yourself. In your code, SQR(b+5) will become: (b+5*b+5), or (3+5*3+5). Now remember your operator precedence rules: * before +. So this is evaluated as: (3+15+5), or 23.
The second version of the macro:
#define SQR(x) ((x) * (x))
Is correct, because you're using the parens to sheild your macro arguments from the effects of operator precedence.
This page explaining operator preference for C has a nice chart. Here's the relevant section of the C11 reference document.
The thing to remember here is that you should get in the habit of always shielding any arguments in your macros, using parens.
Because (3+5*3+5 == 23).
Whereas ((3+5)*(3+5)) == 64.
The best way to do this is not to use a macro:
inline int SQR(int x) { return x*x; }
Or simply write x*x.
The macro expands to
a = b+5*b+5;
i.e.
a = b + (5*b) + 5;
So 23.
After preprocessing, SQR(b+5) will be expanded to (b+5*b+5). This is obviously not correct.
There are two common errors in the definition of SQR:
do not enclose arguments of macro in parentheses in the macro body, so if those arguments are expressions, operators with different precedences in those expressions may cause problem. Here is a version that fixed this problem
#define SQR(x) ((x)*(x))
evaluate arguments of macro more than once, so if those arguments are expressions that have side effect, those side effect could be taken more than once. For example, consider the result of SQR(++x).
By using GCC typeof extension, this problem can be fixed like this
#define SQR(x) ({ typeof (x) _x = (x); _x * _x; })
Both of these problems could be fixed by replacing that macro with an inline function
inline int SQR(x) { return x * x; }
This requires GCC inline extension or C99, See 6.40 An Inline Function is As Fast As a Macro.
A macro is just a straight text substitution. After preprocessing, your code looks like:
int main()
{
int a, b=3;
a = b+5*b+5;
printf("%d\n",a);
return 0;
}
Multiplication has a higher operator precedence than addition, so it's done before the two additions when calculating the value for a. Adding parentheses to your macro definition fixes the problem by making it:
int main()
{
int a, b=3;
a = (b+5)*(b+5);
printf("%d\n",a);
return 0;
}
The parenthesized operations are evaluated before the multiplication, so the additions happen first now, and you get the a = 64 result that you expect.
Because Macros are just string replacement and it is happens before the completion process. The compiler will not have the chance to see the Macro variable and its value. For example: If a macro is defined as
#define BAD_SQUARE(x) x * x
and called like this
BAD_SQUARE(2+1)
the compiler will see this
2 + 1 * 2 + 1
which will result in, maybe, unexpected result of
5
To correct this behavior, you should always surround the macro-variables with parenthesis, such as
#define GOOD_SQUARE(x) (x) * (x)
when this macro is called, for example ,like this
GOOD_SQUARE(2+1)
the compiler will see this
(2 + 1) * (2 + 1)
which will result in
9
Additionally, Here is a full example to further illustrate the point
#include <stdio.h>
#define BAD_SQUARE(x) x * x
// In macros alsways srround the variables with parenthesis
#define GOOD_SQUARE(x) (x) * (x)
int main(int argc, char const *argv[])
{
printf("BAD_SQUARE(2) = : %d \n", BAD_SQUARE(2) );
printf("GOOD_SQUARE(2) = : %d \n", GOOD_SQUARE(2) );
printf("BAD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as 2 + 1 * 2 + 1 \n", BAD_SQUARE(2+1) );
printf("GOOD_SQUARE(2+1) = : %d ; because the macro will be \
subsituted as (2 + 1) * (2 + 1) \n", GOOD_SQUARE(2+1) );
return 0;
}
Just enclose each and every argument in the macro expansion into parentheses.
#define SQR(x) ((x)*(x))
This will work for whatever argument or value you pass.
Related
Why this macro gives output 144, instead of 121?
#include<iostream>
#define SQR(x) x*x
int main()
{
int p=10;
std::cout<<SQR(++p);
}
This is a pitfall of preprocessor macros. The problem is that the expression ++p is used twice, because the preprocessor simply replaces the macro "call" with the body pretty much verbatim.
So what the compiler sees after the macro expansion is
std::cout<<++p*++p;
Depending on the macro, you can also get problems with operator precedence if you are not careful with placing parentheses where needed.
Take for example a macro such as
// Macro to shift `a` by `b` bits
#define SHIFT(a, b) a << b
...
std::cout << SHIFT(1, 4);
This would result in the code
std::cout << 1 << 4;
which may not be what was wanted or expected.
If you want to avoid this, then use inline functions instead:
inline int sqr(const int x)
{
return x * x;
}
This has two things going for it: The first is that the expression ++p will only be evaluated once. The other thing is that now you can't pass anything other than int values to the function. With the preprocessor macro you could "call" it like SQR("A") and the preprocessor would not care while you instead get (sometimes) cryptical errors from the compiler.
Also, being marked inline, the compiler may skip the actual function call completely and put the (correct) x*x directly in the place of the call, thereby making it as "optimized" as the macro expansion.
The approach of squaring with this macro has two problems:
First, for the argument ++p, the increment operation is performed twice. That's certainly not intended. (As a general rule of thumb, just don't do several things in "one line". Separate them into more statements.). It doesn't even stop at incrementing twice: The order of these increments isn't defined, so there is no guaranteed outcome of this operation!
Second, even if you don't have ++p as the argument, there is still a bug in your macro! Consider the input 1 + 1. Expected output is 4. 1+1 has no side-effect, so it should be fine, shouldn't it? No, because SQR(1 + 1) translates to 1 + 1 * 1 + 1 which evaluates to 3.
To at least partially fix this macro, use parentheses:
#define SQR(x) (x) * (x)
Altogether, you should simply replace it by a function (to add type-safety!)
int sqr(int x)
{
return x * x;
}
You can think of making it a template
template <typename Type>
Type sqr(Type x)
{
return x * x; // will only work on types for which there is the * operator.
}
and you may add a constexpr (C++11), which is useful if you ever plan on using a square in a template:
constexpr int sqr(int x)
{
return x * x;
}
Because you are using undefined behaviour. When the macro is expanded, your code turns into this:
std::cout<<++p*++p;
using increment/decrement operators on the same variable multiple times in the same statement is undefined behaviour.
Because SQR(++p) expands to ++p*++p, which has undefined behavior in C/C++. In this case it incremented p twice before evaluating the multiplication. But you can't rely on that. It might be 121 (or even 42) with a different C/C++ compiler.
I saw this below code in an website.
I could not able to understsnd how the result is coming as 11, instead of 25 or 13.
Why I am thinking 25 because SQ(5) 5*5
or 13 because
SQ(2) = 4;
SQ(3) = 9;
may be final result will be 13 (9 + 4)
But surprised to see result as 11.
How the result is coming as 11?
using namespace std;
#define SQ(a) (a*a)
int main()
{
int ans = SQ(2 + 3);
cout << ans << endl;
system("pause");
}
The preprocessor does a simple text substitution on the source code. It knows nothing about the underlying language or its rules.
In your example, SQ(2 + 3) expands to (2 + 3*2 + 3), which evaluates to 11.
A more robust way to define SQ is:
#define SQ(a) ((a)*(a))
Now, SQ(2 + 3) would expand to ((2 + 3)*(2 + 3)), giving 25.
Even though this definition is an improvement, it is still not bullet-proof. If SQ() were applied to an expression with side effects, this could have undesired consequences. For example:
If f() is a function that prints something to the console and returns an int, SQ(f()) would result in the output being printed twice.
If i is an int variable, SQ(i++) results in undefined behaviour.
For further examples of difficulties with macros, see Macro Pitfalls.
For these reasons it is generally preferable to use functions rather than macros.
#define expansions kick in before the compiler sees the source code. That is why they are called pre-processor directives, the processor here is the compiler that translates C to machine readable code.
So, this is what the macro pre-processor is passing on to the compiler:
SQ(2 + 3) is expanded as (2 + 3*2 + 3)
So, this is really 2 + 6 + 3 = 11.
How can you make it do what you expect?
Enforce the order of evaluation. Use (), either in the macro definition or in the macro call.
OR
Write a simple function that does the job
The C preprocessor does textual substitution before the compiler interprets expressions and C syntax in general. Consequently, running the C preprocessor on this code converts:
SQ(2 + 3)
into:
2 + 3*2 + 3
which simplifies to:
2 + 6 + 3
which is 11.
#define preprocesor
Syntax :
# define identifier replacement
When the preprocessor encounters this directive, it replaces any occurrence of identifier in the rest of the code by replacement.
This replacement can be an expression, a statement, a block or simply anything.
The preprocessor does not understand C, it simply replaces any occurrence of identifier by replacement.
# define can work also with parameters to define function macros:
# define SQ(a) (a*a)
will replace any occurance of SQ(a) with a*a at compile time.
Hence,
SQ(2+3) will be replaces by 2+3*2+3
The computation is performed after the replacement is done.
hence answer 2+3*2+3=11
For your implementation, the value will expand to 2+3 * 2+3 which will result into 2+6+3=11.
You should define it as:
#define SQ(x) ({typeof(x) y=x; y*y;})
Tested on gcc, for inputs like
constants,
variable,
constant+const
const+variable
variable++ / ++variable
function call, containing printf.
Note: typeof is GNU addition to standard C. May not be available in some compilers.
It's just a replacement before compilation
so you should try this out :
#define SQ(a) ((a)*(a))
In your case , SQ(2 + 3) is equivalent to (2+3*2+3) which is 11.
But correcting it to as I wrote above, it will be like, ((2+3)*(2+3)) which is 5*5 = 25 that's the answer you want.
When I define this macro:
#define SQR(x) x*x
Let's say this expression:
SQR(a+b)
This expression will be replaced by the macro and looks like:
a+b*a+b
But, if I put a ++ operator before the expression:
++SQR(a+b)
What the expression looks like now? Is this ++ placed befor every part of SQR paramete? Like this:
++a+b*++a+b
Here I give a simple program:
#define SQR(x) x*x
int a, k = 3;
a = SQR(k+1) // 7
a = ++SQR(k+1) //9
When defining macros, you basically always want to put the macro parameters in parens to prevent the kind of weird behaviour in your first example, and put the result in parens so it can be safely used without side-effects. Using
#define SQR(x) ((x)*(x))
makes SQR(a+b) expand to ((a+b)*(a+b)) which would be mathematically correct (unlike a+b*a+b, which is equal to ab+a+b).
Putting things before or after a macro won't enter the macro. So ++SQR(x) becomes ++x*x in your example.
Note the following:
int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
// since preincrement will affect the value of a before it is read.
You're seeing the ++SQR(a+b) appear to increment by 2 since the preincrement kicks in before a i read either time, i.e. a increments, then is used twice and so the result is 2 higher than expected.
NOTE As #JonathanLeffler points out, the latter call invokes undefined behaviour; the evaluation is not guaranteed to happen left-to-right. It might produce different results on different compilers/OSes, and thus should never be relied on.
For C++ the right way to define this macro is to not use a macro, but instead use:
template<typename T> static T SQR( T a ) { return a*a; }
This will get right some horrible cases that the macro gets wrong:
For example:
SQR(++a);
with the function form ++a will be evaluated once. In the macro form you get undefined behaviour as you modify and read a value multiple times between sequence points (at least for C++)
A macro definition just replaces the code,hence it is generally preferable to put into parenthesis otherwise the code may replaced in a way you don't want.
Hence if you define it as :
#define SQR(x) ((x)*(x))
then
++SQR(a+b) = ++((a+b)*(a+b))
In your example, ++SQR(a+b) should be expanded as ++a+b*a+b.
So, if a == 3 and b == 1 you will get the answer 9 if the compiler evaluates it from left to right.
But your statement ++SQR(3+1) is not correct because it will be expanded as ++3+1*3+1 where ++3 is invalid.
In your preprocessor it evaluates to ++a+b*a+b. The right way is put brackets around each term and around the whole thing, like:
#define SQR(x) ((x)*(x))
I don't understand why the result is going to be 36. Can somebody explain to me what is happening here and what the preprocessor does?
#include <iostream>
#define QUADRAT(x) ((x) * (x))
using namespace std;
int main()
{
double no = 4.0;
double result = QUADRAT(++no);
cout << result;
return 0;
}
Thanks alot :>
The preprocessor will replace QUADRAT(++no) with ((++no) * (++no)) in that example.
That would increment no twice, if it weren't for the fact that there are no sequence points between the two increments, so you are actually causing undefined behaviour. Any output you see is valid because no one can tell what will happen.
The preprocessor is a basically a copy-and-paste engine. Note that a macro is not a function; instead, it's expanded inline. Consider what happens to your code when the macro is expanded.
This line:
double result = QUADRAT(++no);
gets expanded to this:
double result = ((++no) * (++no));
The way that this ends up running is equivalent to:
no = no + 1;
no = no + 1;
result = no * no;
It runs this way because the increments are performed before the multiplication: the preprocessor does a textual copy of what you pass it, so it copies the "++no" so that it shows up twice in the final code, and the increment of each ++no happens before the result is computed. The way to fix this is to use an inline function:
inline double QUADRAT(double x) { return x * x; }
Most modern compilers will expand this code out without doing a textual substitution - they'll give you something as fast as a preprocessor definition, but without the danger of having issues like the one you are facing.
What happens is a sort of literal substitution of ++no in place of x, it is like you have written:
double result = ((++no) * (++no));
What is the result... it should be undefined behaviour (you get 36 by chance), and g++ with -Wall agrees with me.
At: http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/
It mentions a directive called "Macro defines". What do we mean when we say "Macro"?
Thanks.
A macro is a preprocessor directive that defines a name that is to be replaced (or removed) by the preprocessor right before compilation.
Example:
#define MY_MACRO1 somevalue
#define MY_MACRO2
#define SUM(a, b) (a + b)
then if anywhere in the code (except in the string literals) there is a mention of MY_MACRO1 or MY_MACRO2 the preprocessor replaces this with whatever comes after the name in the #define line.
There can also be macros with parameters (like the SUM). In that case the preprocessor recognizes the arguments, example:
int x = 1, y = 2;
int z = SUM(x, y);
preprocessor replaces like this:
int x = 1, y = 2;
int z = (x + y);
only after this replacement the compiler gets to compile the resulting code.
A macro is a code fragment that gets substituted into your program by the preprocessor (before compilation proper begins). This may be a function-like block, or it may be a constant value.
A warning when using a function-like macro. Consider the following code:
#define foo(x) x*x
If you call foo(3), it will become (and be compiled as) 3*3 (=9). If, instead, you call foo(2+3), it will become 2+3*2+3, (=2+6+3=11), which is not what you want. Also, since the code is substituted in place, foo(bar++) becomes bar++ * bar++, incrementing bar twice.
Macros are powerful tools, but it can be easy to shoot yourself in the foot while trying to do something fancy with them.
"Macro defines" merely indicate how they are specified (with #define directives), while "Macro" is the function or expression that is defined.
There is little difference between them aside from semantics, however.