Confused by squaring macro SQR in c [duplicate] - c++

This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Confusion with Macro expansion [duplicate]
(3 answers)
Closed 9 years ago.
This question was asked to me in a mock interview...Really got surprised to find awkward answers...
consider a macro:
#define SQR(x) (x*x)
Example 1:
SQR(2) //prints 4
Example 2:
If SQR(1+1) is given it doesn't sum (1+1) to 2 but rather ...
SQR(1+1) //prints 3
Awkward right? What is the reason? How does this code work?
NOTE: I searched SO but couldn't find any relevant questions. If there are any kindly please share it!

SQR(1+1) expands to 1+1*1+1 which is 3, not 4, correct?
A correct definition of the macro would be
#define SQR(x) ((x)*(x))
which expands to (1+1)*(1+1) and, more important, shows you one of the reasons you shouldn't use macros where they aren't needed. The following is better:
inline int SQR(int x)
{
return x*x;
}
Furthermore: SQR(i++) would be undefined behavior if SQR is a macro, and completely correct if SQR is a function.

The problem is that macros are doing textual substition before it is compiled, so the macro expands to 1+1*1+1

That is why you always put arguments to macros into ():
#define SQR(x) ((x)*(x))

Related

#define macro doesn't as expect [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I got this problem wrong on a test and am really confused why.
For the given code below, I thought that the output would be 0. Can someone please explain why it isn't?
#include<iostream>
using namespace std;
#define A 0
#define B A+1
#define C 1-B
int main{
cout<<C;
return(0);
}
The correct answer (and real output) is 2.
You will get the correct answer if you expand the macros step by step.
cout<<C;
is
cout<<1-B;
is
cout<<1-A+1;
is
cout<<1-0+1;
which is
cout << 2;
Remember that macros don't work like variables. If you use variables you will get a different answer.
int a = 0;
int b = a+1; // b is 1.
int c = 1-b; // c is 0
cout << c; // Expect 0 in output.
The preprocessor expands macros by doing text substitution, and producing code that is then compiled. The preprocessor (mostly) does not understand expressions - that is handled by a later phase of compilation (after the preprocessor is done).
So C expands to 1-B which expands 1-A+1 which expands to 1-0+1.
This is treated by the compiler as an expression. 1-0+1 gives 2
To get the result (zero) that you expect, you need to use
#define A 0
#define B (A+1)
#define C (1-B)
so C expands to (1-B) which expands (1-(A+1)) which expands to (1-(0+1)), which is evaluated (by the compiler, not the preprocessor) as an expression and gives 0.
Bear in mind that A, B, and C are not variables. They are macros - i.e. directions to the preprocessor on how to do text substitution.
I thought that the output would be 0. Can someone please explain why
it isn't?
Because C expands to 1-B
Now, B expands to A+1.
Now, again, A expands to 0
Filling the gaps:
Since A expanded to 0 then B gets replaced by 0+1
And replacing B in the expression 1-B then becomes 1-0+1
C = 1-B
// ^^^
// A+1
// ^^^
//
// = 1-0+1
Macros are so C89, c++11 came with a better solution to do this at compile time: constexpr.
#include<iostream>
using namespace std;
constexpr auto A = 0;
constexpr auto B = A + 1;
constexpr auto C = 1 - B;
int main{
cout<<C;
return(0);
}
Advantages are: easier to use, as you know the syntax and behavior already. Undefined behavior ain't allowed, which makes this safer. And you can't have circular dependencies giving strange side effects, as it wouldn't compile otherwise.

How to get C compiler #error if a sizeof(struct ...) not equal to a given number? [duplicate]

This question already has answers here:
How can I use "sizeof" in a preprocessor macro?
(13 answers)
Closed 3 years ago.
How to get C compile time #error if a sizeof(struct ...) not equal to a given number?
The question is from programming course, where I'd like to avoid to run miss-sized binary code.
(The sizeof operator, as we know, doesn't work in #if .. #endif directive.)
How to get C compile time #error if a sizeof(struct ...) not equal to a given number?
You cannot, because the pre-processor knows nothing about sizes of types.
You can however static_assert:
static_assert(sizeof(T) == N, "T must have size N")
In C, the keyword is _Static_assert, also available through macro static_assert in <assert.h>.
Don't. You already explained why.
In modern C++ you can write:
static_assert(sizeof(T) == 42);
Although it is better to write code that doesn't care what the size of T is.
#include <assert.h>
//T should have size 10
static_assert(sizeof(T) == 10)
It's available only the latest C compiler

Double boolean negation operator [duplicate]

This question already has answers here:
Double Negation in C++
(14 answers)
double negation in C : is it guaranteed to return 0/1?
(2 answers)
Closed 5 years ago.
I came across this piece of code from the Microsoft implementation of GSL (the C++ Guideline Support Library):
#if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x))
#endif
I read about the __builtin_expect (here and here), but it is still unclear to me what is the purpose of the double boolean negation operator in (!!(x)). Why is it used?
The file in question is this one.
__builtin_expect works with strict equality, so the point of double negation here is to make sure all truthy values are converted to 1 (and thus match the 1 in GSL_LIKELY), and all the falsy values match the 0 in GSL_UNLIKELY.
The double negation is kept even if __builtin_expect is not available to keep uniformity (as the caller may store the return value for other uses besides as a condition in an if).

How to use logical XOR operator in macro? NOT how to defined XOR operator by macro [duplicate]

This question already has answers here:
Why is there no ^^ operator in C/C++?
(7 answers)
Logical XOR operator in C++?
(11 answers)
Closed 6 years ago.
Is there any tricky way to use logical xor operator ^^ in macro in C, C++, Objective-C?
I have tried applying ^^ directly in Objective-C, it does not work.
Edited: let me clarify my answer.
What I want is to use xor operator in macro. It does not mean "how to define the xor operator by a macro.
I.e, I want something like
#if defined(x) ^^ TARGET_OS_IOS ^^ __cplusplus
For seconds after posting the question, I figured out the answer my self.
!(A) != !(B) will be equivalent to xor operator
A better solution in case the number of operands is different than 2
!(A) ^ !(B) ^ !(C) ^ ...

Output when using Pre-processors in C++ [duplicate]

This question already has answers here:
Using Parentheses in Define Preprocessor Statements
(4 answers)
Closed 7 years ago.
Here f(3+3) is replaced by f(6)= 6*6 ?
So the output should be 36 na? So why and how the answer is 15?
#include <iostream>
#define f(a) a*a
using namespace std;
int main(){
cout<<f(3+3);
}
The macro invocation
f(3 + 3)
is replaced by
3 + 3 * 3 + 3
This is the reason that arguments to macros usually is put between parentheses:
#define f(a) (a) * (a)
As a side-note, if you use a variable instead of a literal integer, and does something like
int a = 3;
int result = f(a++);
Then the macro is replaced by
(a++) * (a++)
leading to a being incremented twice. And in an unknown order, leading to undefined behavior.
In C++ there are seldom any use for function-like macros any more, and with all the problems with them (as shown above) you really should not use them. Use functions, they behave correctly, the compiler can still inline them, and they are type-safe (think about what would happen if you did e.g. f("3"), you might get weird errors that are hard to track down).
Because 3 + 3 × 3 + 3 = 15.
Try using parentheses to achieve what you want.