do{}while(0) vs an empty statement [duplicate] - c++

This question already has answers here:
do { ... } while (0) — what is it good for? [duplicate]
(5 answers)
Why use apparently meaningless do-while and if-else statements in macros?
(9 answers)
Closed 4 years ago.
Trying to make a logging system that only logs data when a certain macro is defined, I've done something like this:
#ifdef _DEBUG
#define foo(a) std::cout << a << std::endl
#else
#define foo(a)
#endif
int main()
{
foo("Hello!");
return 0;
}
The function main, after pre-processing, expands to:
int main()
{
;
return 0;
}
However, on some places, I saw that people use do{}while(0) instead of an empty macro. I suppose that a compiler would optimize away both of these but I'm wondering is there an advantage that one has over another?
I am aware of the need for both an empty statement and do{}while(0) but what I do not know is the difference between the two.
I don't believe my question was fully read and compared to the ones that have been provided when marking as duplicate.

Related

Is it possible to make a compile-time (macros) branching based on assert condition? [duplicate]

This question already has answers here:
How can I use "sizeof" in a preprocessor macro?
(13 answers)
C++ Getting the size of a type in a macro conditional
(7 answers)
Does the sizeof operator work in preprocessor #if directives?
(4 answers)
sizeof in preprocessor command doesn't compile with error C1017
(4 answers)
sizeof() is not executed by preprocessor
(9 answers)
Closed 4 months ago.
For example, I want something similar in meaning to this:
//Somethere in Windows header
struct COUPLE {
WORD part0;
WORD part1;
}
//In my code
#if sizeof(COUPLE) == sizeof(INT)
#define COUPLE_TO_INT(arg) (*((INT*)((void*)&arg)))
#else
inline INT COUPLE_TO_INT(const COUPLE &arg) {
return ((INT)arg.part1 << 16) + arg.part0;
}
#endif
Of course, the code from the example is not compiled.
And, of course, I can do with just the INT COUPLE_TO_INT(const COUPLE &arg) function, but as I noticed, in most cases it is not required and I can do with reinterpret_cast, which requires less resources (shifting and summation). However, there may be situations where padding breaks this mechanism, so a backup path is required.
It is clear that I cannot influence the alignment of the structures from the header in any way, but I can find out their size and act on this.
Is it possible to branch a macro based on an C++ assert or something of the same kind?
You could use constexpr if in a normal function, e.g.
int coupleToInt(const COUPLE& c) {
if constexpr (sizeof(COUPLE) == sizeof(int)) {
// ...
}
else {
// ...
}
}
This feature is available since C++17 and you tagged the question as such. The condition is evaluated at compile time.

Can someone please explain why the output of this code is 3 and not 4? [duplicate]

This question already has answers here:
Unexpected Result in Macro
(2 answers)
Closed 2 years ago.
Can someone please explain why the output of this code is 3 and not 4?
#define square(x) (x*x)
int main () {
int x,y=1;
x=square(y+1);
printf("%d\n",x);
return 0;
}
The reason is that what preprocessor does about macros is quite like a search-replace. So you get y+1*y+1 which gives three. To avoid such problems
wrap every variable in macro definition with parentheses #define square(x) ((x)*(x))
use functions instead (prefered as less likely to run into random errors)

How does #define work in C++ [duplicate]

This question already has answers here:
Macro Expansion
(7 answers)
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 4 years ago.
#include <iostream>
using namespace std;
#define squareOf(x) x*x
int main() {
// your code goes here
int x;
cout<<squareOf(x+4);
return 0;
}
I thought the answer would come as 16 but it came out as 4.
I am confused how does this works.
16 would never be the result here. Let's say you would have initialized x with 0, then you would have your x+4 replaced by x+4*x+4 which would evaluate as 0+4*0+4 = 4.
Preprocessor macros replace source code, they are not functions.
You might now think that maybe
#define squareOf(x) (x)*(x)
would be better, but consider that then
int x = 2;
int y = squareOf(x++);
would result in y = (2)*(3) = 6, not in 4.
If you do not have a really good reason, avoid preprocessor macros. There are good reasons, but if something behaves like a function, better make it a function.
Now take a look at this:
template <class T>
inline T squareOf(const T& number)
{
return number*number;
}
As inline, it does also replace code (at least if the compiler wants so), but here, this one actually behaves like a function (since it is one). Wouldn't expect a bad outcome from that one.

a macro substitution involving concatenation and line number [duplicate]

This question already has answers here:
Creating C macro with ## and __LINE__ (token concatenation with positioning macro)
(3 answers)
Closed 6 years ago.
I would like to have a macro that produce something like L17, where 17 is the line number when the macro is invoked. However the following only produce L__LINE__
#define STOP L##__LINE__
Wonder if there is a way to make the __LINE__ evaluate before concatenation.
You need a double concat macro wrapper:
#define CONCAT0(x,y) x ## y
#define CONCAT(x,y) CONCAT0(x,y)
#define STOP CONCAT(L,__LINE__)
int main() {
int STOP = 42;
L5 = 41;
}

why macros return what we are not expected [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Problem with Macros
Hi all
I have defined this macro:
#define SQ(a) (a*a)
and called it in this way:
std::cout << SQ(2+3) << '\n';
the output was 11. Why ?
Thanks
Macros do only simple text manipulation, i.e. they are very stupid that way in that they don't see 'code', only 'text' which are then sent to to the C/C++ parser for validation.
SQ(2+3) becomes (2+3*2+3)
That's why you should use templates, which are a bit smarter, they would do what you expected: first calculate 2+3, then do 5*5.
Because the expansion of SQ in your example gives:
std::cout << (2+3*2+3) << '\n';
A better way to define the macro would be
#define SQ(a) ((a)*(a))
which solves the precedence issue in this case.
Better still would be to use a function which avoids any issues with the passed expression being evaluated more than once.
E.g. as a template:
template<class T>
T SQ(T a) { return a * a; }
Fix your macro to:
#define SQ(a) ((a)*(a))
Others already have the answer. The "fix" (if you must use macros at all) is to wrap all your params with parens, e.g.
#define SQ(a) ((a)*(a))
In most cases, you're better off using templates as this will still perform compile-time expansion for speed, but also provides language support for syntax and type checking.