What does this C++ define macro do? - c++

What does this define macro do? I assumed that this will print the given string to the standard output, but it just not printed out nothing. Am I wrong about this?
#define SCOPE_LOGGER(...)
...
void someClass::someFunction() { SCOPE_LOGGER("someClass::someFunction()"); ... }

As per KamilCuk's answer, that macro expands to nothing.
However, most likely it does expand to something through some other preprocessing conditional path, i.e. imho that line appears in the code like this:
#ifdef DEBUG
#define SCOPE_LOGGER(...) something real that does the logging
#else
#define SCOPE_LOGGER(...)
#endif
That's the only way that line can make sense.

What does this define macro do?
Defines a macro function that takes any number of arguments and expands to nothing.
Am I wrong about this?
Because the macro expands to nothing, SCOPE_LOGGER("someClass::someFunction()") is removed from the code. Fun fact: the trailing ; stays.

Related

How does #define know when to stop looking?

I use a macro in C++ to switch between compiling logging or not:
#define MAYBE_LOG(msg)
#ifdef PRINT_MSGS
ALWAYS_LOG(msg)
#endif
How does the #define know where the ending is? The #endif refers to the #ifdef, not the #define.
#define ends at end of the line (which might be extended with final \)
The code in the question does two separate things: it defines a macro named MAYBE_LOG with no body and, if PRINT_MSGS is defined, it uses a macro named ALWAYS_LOG. If that's not what it's supposed to do, then, yes, it needs to be changed. Since the question doesn't say what the code is supposed to do, this is just a guess:
#ifdef PRINT_MSGS
#define MAYBE_LOG(msg) ALWAYS_LOG(msg)
#else
#define MAYBE_LOG(msg)
#endif
The reason for doing it this way (and not using \ on each line to extend the macro definition is that you can't put #if conditions inside the definition of a macro.

how to save typing in c++

I have a piece of code like this I need to put in front of a lot of functions.
#ifdef __AA__
__BB__ __CC__
#endif
But it's just too trivial to write it every time and it makes code looks ugly.
Is there any way I can define something like macro to make it short? Thanks.
You can define a preprocessor macro conditionally:
#ifdef __AA__
# define FN_INTRO __BB__ __CC__
#else
# define FN_INTRO
#endif
Then before each function you can just write FN_INTRO instead of the whole thing.

Function-like macros without body but different names of argument

The following code:
#define MYDEF(x)
#define MYDEF(y)
int main() {}
gives me an error (or warning if pedantic-errors is disabled):
'MYDEF' macro redefined
The reason is different names for unused argument (more over, there is no body in macro). But why? In which situations it can be a problem?
Because macros are not functions. They are textual replacements done by the preprocessor and can't be overloaded.
It is (almost) similar to find and replace in your editor. Find all the occurences of MYDEF and replace it with (empty string in your case). It's more complicated, of course, but the idea is the same.
And you can't overload this find and replace, can you? :)
The macro can be redefined, and the macro is uniquely determined by the macro name. For example, code like this :
#define MYDEF(x) //the name of the macro is 'MYDEF'
#define MYDEF(x, y) //the name of the macro is 'MYDEF' too
MYDEF(x) will be redifined(or covered) by MYDEF(x, y), you can't write code MYDEF(x) any more after defining MYDEF(x, y)
so, if you write code :
#define MYDEF(x)
#define MYDEF(y) //(There compiler will give warning). You can write
//`#undef MYDEF` before `#define MYDEF(y)` to avoid it.
MYDEF(x) will be redifined by MYDEF(y).

Can macros in C++ define macros?

I was wondering if it was possible to define a macro in C++ that defines another macro that can be used in later code. Is this possible, or is the preprocessor used by g++ too limited for this?
No, you cannot define a macro within the expansion of another macro.
Nope, you can't define a macro as a macro.
The preprocessor makes only one pass over the source code, so this is not possible. However, you could use an external tool to perform some preprocessing ahead of compilation, like m4.
You can do something like this, its not exactly what you are looking for, but it might help.
#ifdef ENABLE_MACRO_1
#define PRINT_MACRO(varName) \
std::cout<<varName<<std::endl;
#else
#define PRINT_MACRO(varName) \
//do nothing
#endif
So you can define a macro depending on another preprecursor condition which was defined defined.

Macros in macros

Is it possible to put a macro in a macro in c++?
Something like:
#define Something\
#ifdef SomethingElse\ //do stuff \
#endif\
I tried and it didn't work so my guess is it doesn't work, unless there's some sort of syntax that can fix it?
Macros, yes. Preprocessor directives, which are what you posted, no
No, but you can simply refactor this by pulling the #ifdef out as the toplevel, and using two different #define Something ... versions for the true and false branches of the #ifdef.
You can't use preprocessor directives in macros, but if we want to check if SomethingElse is defined and call a different macro, you could accomplish it like this(requires a c99 preprocessor and Boost.Preprocessor library):
#define PP_CHECK_N(x, n, ...) n
#define PP_CHECK(...) PP_CHECK_N(__VA_ARGS__, 0,)
//If we define SomethingElse, it has to be define like this
#define SomethingElse ~, 1,
#define Something \
BOOST_PP_IF(PP_CHECK(SomethingElse), MACRO1, MACRO2)
If SomethingElse is defined it will call MACRO1, otherwise it will call MACRO2. For this to work, SomethingElse has to be defined like this:
#define SomethingElse ~, 1,
By the way, this won't work in Visual Studio, because of a bug in their compiler, there is a workaround here: http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement
No. I answered this in c++ macros with memory?
If you want to inspect or alter the preprocessing environment, in other words to define a preprocessing subroutine rather than a string-replacement macro, you need to use a header, although the legitimate reasons for doing so are few and far between.