This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 1 year ago.
#include <stdio.h>
#define ONE 3 > 2 ? 16 : 64
#define TWO ONE/16
int main () {
printf("%d\n", TWO);
return 0;
}
I write two #define, but output is 16, while I expected it was 1.
Why does this happen?
Macros are a simple text replacement. When preprocessor goes through the code, it replaces
printf("%d\n", TWO);
with
printf("%d\n", ONE/16);
and then with
printf("%d\n", 3 > 2 ? 16 : 64/16);
Then compiler can see that ternary operator condition evaluates to true and takes the first result - 16.
You probably wanted first macro to be wrapped in parentheses:
#define ONE (3 > 2 ? 16 : 64)
But I'd strongly suggest to avoid using macros wherever possible. As comments suggest,
constexpr auto ONE = 3 > 2 ? 16 : 64;
would give you the expected result.
The preprocessor is only a simple text replacing.
If you replace it by hand or simply use the gcc -E option ( maybe different on other compilers ) you get:
#define TWO 3 > 2 ? 16 : 64/16
What you expect is can be simply achieved by using braces:
#define ONE (3 > 2 ? 16 : 64)
#define TWO ONE/16
BTW: You should not longer use macros at all and replace it by compile time constant expressions like:
constexpr auto ONE = 3 > 2 ? 16 : 64;
The benefit is, that you get errors or warnings if you did something wrong and all expressions are type safe. Macros, as said, are only doing text replacement without any syntax check for the later on used language.
Related
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.
Im trying to learn some c++, and I bumped into this code:
static const unsigned char t_CountBits13[8192] = {
#define B2(n) n, n+1, n+1, n+2
#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
#define B8(n) B6(n), B6(n+1), B6(n+1), B6(n+2)
#define B10(n) B8(n), B8(n+1), B8(n+1), B8(n+2)
#define B12(n) B10(n), B10(n+1), B10(n+1), B10(n+2)
B12(0), B12(1)
};
I think this is pretty weird !
Question 1: Is this the same as:
#define B2(n) n, n+1, n+1, n+2
#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
#define B8(n) B6(n), B6(n+1), B6(n+1), B6(n+2)
#define B10(n) B8(n), B8(n+1), B8(n+1), B8(n+2)
#define B12(n) B10(n), B10(n+1), B10(n+1), B10(n+2)
static const unsigned char t_CountBits13[8192] = {B12(0), B12(1)};
Question 2:
#define B2(n) n, n+1, n+1, n+2
Am I right to think that a C++ function can only return one value ? Because it seems like you define a function here that returns multiple (like lua for example)
Kind regards!
Answer 1: The array will be initialized with the same value. The preprocessed result will look a bit different with regards to white space, so textually it isn't the same, but the result of compilation should be identical.
Answer 2: As mentioned in the comments, these are not C++ functions, but are macros interpreted by the C pre-processor. These result in text expansion prior to the compiler interpreting it. The expansion in your example is too large to show here (2 * 4^6 = 8192 elements is a lot). I'll reduce it for an example.
Original source code:
static const unsigned char data[] = {
#define B2(n) n, n+1
#define B4(n) B2(n), B2(n+1)
B4(1), B4(2)
};
output of preprocessor (for example, as output by gcc -E tst.c:
# 1 "tst.c"
# 1 "<command-line"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line" 2
# 1 "tst.c"
static const unsigned char data[] = {
1, 1 +1, 1 +1, 1 +1 +1, 2, 2 +1, 2 +1, 2 +1 +1
};
Note the blank lines where the preprocessing directives were. Also note that the values are not the result of the arithmetic, but the text expansion. This is the code the compiler will actually interpret. Also note that the expansions are recursive through the #define macros defined above.
The lines starting with # are additional information from the preprocessor and includes things like defines from the command line and file information. It's fairly bland in the example, but if you were to have a #include <somefile.h> you'd see its contents, and the contents of the files it includes (recursively), as well as some # lines indicating the real line numbers of those locations (often used by the compiler for displaying warning and error messages, since by the time it gets it the line that used to be your line 5 might now be line 2592, but you'd expect the warning to indicate line 5).
Looking at the output of the preprocessor can be quite helpful debugging weird errors. When the message from the compiler just doesn't make sense, it can be an errant #define replacing text you didn't expect. For example, you might have the following code
int limit(int x) {
if (x > LIMIT) {
return LIMIT;
}
return x;
}
The compiler might say error: expected identifier or '(' before numeric constant on the line int limit(int x) {
If you look at the preprocessed output you might find
int 5(int x) {
and realize that the following line made it into your code (either original source file or from an included file)
#define limit 5
Note how limit is lower case, and we tried naming a function that, but the preprocessor replaced it with the 5. The #define should probably have been LIMIT (all uppercase)
This has been a bit of a long answer, but I hope illustrates the text-replacement nature of #defines and some hints at finding the intermediary representations of your own code.
Note: The actual output of your preprocessor depends on your toolchain. The information above holds for the GNU Compiler Collection. Some toolchains don't actually separate the pre-processor phase from the compilation phase, but simply behave as though they do, which is allowed by the language.
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))
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Double Negation in C++ code
Let's say:
bool var = !!true;
It will assign "true" to the variable. Seems useless, but I was looking at Visual Studio's definition of "assert", and it is:
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
Why does it negate the "_Expression" twice?
I wonder that they want to force the "!" operator to be called (in the case it is overloaded), but that doesn't seem to be a good reason.
!! guarantees that the result will end up as a 1 or a 0, rather than just the value of _Expression or 0. In C, it's unlikely to matter, but in C++ I think it turns the result of the expression into a bool type, which might be useful in some cases. If you did have some API that required a literal 1 or 0 be passed to it, using !! would be a way to make it happen.
It's possible that you might want an int variable that's either 1 or 0.
So you can't for example pass a 5, instead the double negation would turn that 5 into a 1.
Also, have a look at how TRUE is defined:
#ifndef TRUE
#define TRUE 1
#endif
Therefore, an expression like:
int x = 5;
if ( x == TRUE )
{
//....
}
would not pass, whereas
if ( x )
{
//....
}
would.
Its use is to make sure the value is either 0 or 1. I think it's superfluous with C++'s bool type.