c++ macro sideeffect - c++

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.

Related

Why skipping unsigned char breaks the program? [duplicate]

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.

Function with no return statement but compiled and returned right answer

In the section of the code below, there is no return statement in the function but it still compiled and gave the right answer. Is this a normal behavior?
#include <iostream>
int multiply (int x, int y) {
int product = x * y;
}
int main (int argc, char **argv) {
std::cout << multiply(4, 5) << std::endl;
return 0;
}
No, getting the correct answer from the function is not normal behaviour, it's a coincidence. You should not rely on this.
From C++03, 6.6.3 The return statement /2 (and the same section for C++11 as well):
Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
You'll probably find that you're getting the correct answer simply because of the side effects of your calling convention.
For example, if a function value is returned in the (mtyhical) r0 register, it may be that the calculation uses that register within the function to hold the value, before storing it into the memory representing the product variable. So the fact it's in r0 when you return is just a hang-over from the way things are done.
Compiling with different levels of optimisation, or using another compiler, or even compiling on a Tuesday evening during a blue moon may affect the outcome, that's the main problem with undefined behaviour - it's untrustworthy. At a bare minimum, a good compiler would have warned you about this.

#define SQR(x) x*x. Unexpected Answer

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.

How to expand this macro properly?

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))

C++ - Macro defines directive

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.