Why 2 levels of indirection in definition of macro ## operation - c++

In the macro definitions below, there're 2 levels of indirection before the real pasting operation:
#define MACRO_JOIN(a, b) MACRO_JOIN1(a, b)
#define MACRO_JOIN1(a, b) MACRO_JOIN2(a, b)
#define MACRO_JOIN2(a, b) a##b
I know that we need MACRO_JOIN1 because it has no pasting or stringifying so that its arguments can be expanded first.
But what exactly is the purpose of the second indirection MACRO_JOIN? In what situations MACRO_JOIN will work but MACRO_JOIN1 will fail?

Forcing an additional expansion can make a difference where the initial expansion results in something that can be expanded further. A trivial example, given:
#define MACRO(x) x
#define EXPAND(x) x
#define NOEXPAND()
is:
MACRO NOEXPAND() (123)
This expands to MACRO (123). On the other hand, if you force an additional expansion, like so:
EXPAND(MACRO NOEXPAND() (123))
results in:
123
Normally, forcing additional expansions like this is unnecessary: any macro definitions that would cause this to make any difference are generally considered poor style anyway. But with certain specific inputs, it may be useful.
So for a concrete example with your MACRO_JOIN:
MACRO_JOIN(123, MACRO NOEXPAND() (456)) // expands to 123456
MACRO_JOIN1(123, MACRO NOEXPAND() (456)) // expands to 123MACRO (456)

Related

Allowing a custom macro in #ifdef check

Imagine I have some "assert like" functionality, which declares a macro one way if a specific macro is defined, and a different way if it is not:
// in some header assert2.hpp
#ifdef NO_ASSERT2
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here, the NO_ASSERT2 macro is very much like the NDEBUG macro in standard assert(3).
What I'd like to do, however is allow the user to override the NO_ASSERT2 check with their own macro, before including the file. E.g., if you included assert2.hpp like this:
#define NO_ASSERT_KEY NO_ASSERT_CUSTOM
#include "assert2.hpp"
Then the macro NO_ASSERT_CUSTOM would be checked instead of the default NO_ASSERT2 for this translation unit.
It doesn't have to work exactly like the above - I just need some way to override the behavior on a per-file basis, without needing more than the 1 line of boilerplate shown above at the location of the include.
This isn't pretty... but this approach may work for you. It assumes that the macro is defined using either #define FOO, #define FOO 1, or -DFOO (assuming as typical that this creates something equivalent to #define FOO 1).
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(A,B,...) B
#define GLUE3(A,B,C) GLUE3_I(A,B,C)
#define GLUE3_I(A,B,C) A##B##C
#define AGLUE3(A,B,C) AGLUE3_I(A,B,C)
#define AGLUE3_I(A,B,C) A##B##C
#define TEST_ASSERT_KEY GLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT_KEY)
#define NO_ASSERT_PROBE0_NO_ASSERT_KEY AGLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT2)
#define NO_ASSERT_PROBE0_ ,1
#define NO_ASSERT_PROBE0_1 ,1
#define NO_ASSERT_TEST SECOND(TEST_ASSERT_KEY,0)
With this, your usage would be:
#if NO_ASSERT_TEST
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here's a demo at stacked-crooked.
This uses pattern matching in the preprocessor via the indirect SECOND macro. The idea is that it expands to its second argument, but only indirectly... this allows you to construct as the first argument a pattern. Usually that first argument's ignored, but if you want to match something you can set it up to where the first argument would be a macro that expands with a comma; that shifts a new second argument in, replacing the default.
From here it's easier to explain backwards. NO_ASSERT_TEST uses TEST_ASSERT_KEY to construct a pattern with a default of 0. TEST_ASSERT_KEY builds NO_ASSERT_PROBE0_ concatenated with NO_ASSERT_KEY. When NO_ASSERT_KEY is defined, this would build NO_ASSERT_PROBE0_ concatenated with the expansion of what it's defined as. Otherwise it rebuilds the test token using NO_ASSERT_PROBE0_ concatenated with NO_ASSERT2.
Either way this is an indirect paste, so NO_ASSERT_KEY in the former case or NO_ASSERT2 in the latter is expanded first. In the former case, if say NO_ASSERT_KEY is NO_ASSERT_CUSTOM and NO_ASSERT_CUSTOM is not defined, this builds NO_ASSERT_PROBE0_NO_ASSERT_CUSTOM, which is just a normal identifier, which will be ignored, which results in 0 due to the SECOND in NO_ASSERT_TEST. But if NO_ASSERT_CUSTOM is defined per #define NO_ASSERT_CUSTOM, this produces NO_ASSERT_PROBE0_, which expands to ,1, which shifts 1 into the SECOND call in NO_ASSERT_TEST. Likewise if NO_ASSERT_CUSTOM is defined per -DNO_ASSERT_CUSTOM on the command line, that would (typically) make its definition equivalent to #define NO_ASSERT_CUSTOM 1, which would produce NO_ASSERT_PROBE0_1, which expands to ,1.
The cases for when NO_ASSERT_KEY is not defined are similar.
There's probably a prettier way to build this construct, if anyone wants to take a shot.

enable/disable MACRO using __VA_ARGS__

Consider this code:
// Macros to support option testing
#define _CAT(a, ...) a ## __VA_ARGS__
#define SWITCH_ENABLED_false 0
#define SWITCH_ENABLED_true 1
#define SWITCH_ENABLED_0 0
#define SWITCH_ENABLED_1 1
#define SWITCH_ENABLED_ 1
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
I copy from the Marlin, a 3Dprinter Firmware.I dont not how it work to support opthin testing. it is used as follows in Marlin:
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
Obviously the function of this MACRO,ENABLED(USE_WATCHDOG),is to determine whether USE_WATCHDOG is defined.
For example, I really defined USE_WATCHDOG, I substitute it into ENABLED(b), the expansion is _CAT(SWITCH_ENABLED_, USE_WATCHDOG). _CAT will stitch SWITCH_ENABLED_, USE_WATCHDOG into
SWITCH_ENABLED_USE_WATCHDOG, but this macro doesn't exist. Why is the SWITCH_ENABLED_USE_WATCHDOG equivalent to 1 and finally include"watchdog.h"?
Obviously the function of this MACRO,ENABLED(USE_WATCHDOG),is to determine whether USE_WATCHDOG is defined.
Not exactly. The purpose is to determine whether it is defined to 1 or true or nothing on one hand or to 0 or false, or is not defined, on the other. Absent other support (not shown) for other values, if it is defined then its value must be one of those values for compilation to succeed.
For example, I really defined USE_WATCHDOG, I substitute it into ENABLED(b), the expansion is _CAT(SWITCH_ENABLED_, USE_WATCHDOG).
Except where used as the operand of the # or ## preprocessing operator, the arguments to a macro are fully expanded before they are substituted into the macro's replacement text. Therefore, the expansion of ENABLED(USE_WATCHDOG) depends on the definition, if any, of USE_WATCHDOG. For example if it is defined to true:
#define USE_WATCHDOG true
then ENABLED(USE_WATCHDOG) expands to
_CAT(SWITCH_ENABLED_, true)
, which is then subject to being rescanned for additional macro substitutions.
_CAT will stitch SWITCH_ENABLED_, USE_WATCHDOG into SWITCH_ENABLED_USE_WATCHDOG, but this macro doesn't exist.
You've already gone off the rails here. What actually happens, with USE_WATCHDOG defined as above, is that at this stage _CAT(SWITCH_ENABLED_, true) is expanded to
SWITCH_ENABLED_true
(even if true is itself defined as a macro), which is again subject to rescan for additional macro substitutions.
One more round of macro substitution finally reduces this to simply
1
Why is the SWITCH_ENABLED_USE_WATCHDOG equivalent to 1 and finally include"watchdog.h"?
In the code presented, it isn't, but that's unimportant (see above).
Note especially that the _CAT macro is key to making all this work. You need a double layer of macro expansion in order to get USE_WATCHDOG expanded before the result is pasted to SWITCH_ENABLED_, and that seems to be your point of misunderstanding.
Notice these are all defaults for enabling a switch:
#define SWITCH_ENABLED_true 1
#define SWITCH_ENABLED_1 1
#define SWITCH_ENABLED_ 1
Yes, that last one will enable a switch if no switch macro or override exists.
So, you can enable USE_WATCHDOG in the following ways:
Override USE_WATCHDOG (expands to ENABLED(true))
#define USE_WATCHDOG true
Override USE_WATCHDOG (expands to ENABLED(1))
#define USE_WATCHDOG 1
Enable only the switch
#undef USE_WATCHDOG
#define SWITCH_ENABLED_USE_WATCHDOG 1
Have no definitions
#undef USE_WATCHDOG
#undef SWITCH_ENABLED_USE_WATCHDOG
If none of these apply to you, it's possible that one of them is defined in a header you didn't know about, or outside of the code (e.g. project settings, Makefile, etc, or a pre-include file).

macro which defines new macros with an added prefix

We have a profiling framework which can be enabled and disabled at compile time.
All the various calls to the framework are done through macros, eg:
PROFILE_START(msg)
PROFILE_END(msg)
The macros then resolve to the actual profiler call when profiling is enabled, and to nothing when disabled
#ifdef PROFILING_ENABLED
# define PROFILE_START(msg) currentProfiler().start(msg)
# define PROFILE_END(msg) currentProfiler().end(msg)
#else
# define PROFILE_START(msg)
# define PROFILE_END(msg)
#endif
We have various different components in our framework, and I want to enable profiling in each component.
I'd like to be able to selectively enable profiling in each component.
My idea is to prefix all the profiler macros with the component's name, eg:
FOO_PROFILE_START(msg)
FOO_PROFILE_END(msg)
BAR_PROFILE_START(msg)
BAR_PROFILE_END(msg)
I could manually create
#ifdef ENABLE_FOO_PROFILING
# define FOO_PROFILE_START(msg) PROFILE_START(msg)
# define FOO_PROFILE_END(msg) PROFILE_END(msg)
#else
# define FOO_PROFILE_START(msg)
# define FOO_PROFILE_END(msg)
#endif
#ifdef ENABLE_BAR_PROFILING
# define BAR_PROFILE_START(msg) PROFILE_START(msg)
# define BAR_PROFILE_END(msg) PROFILE_END(msg)
#else
# define BAR_PROFILE_START(msg)
# define BAR_PROFILE_END(msg)
#endif
However, this is both tedious and error-prone.
Any time a new feature is added to the profiling framework I would have to find all my component specific macros and add a new macro to each of them.
What I'm looking for is a way to automatically generate the component-prefixed macros.
#ifdef ENABLE_FOO_PROFILING
ADD_PREFIX_TO_ENABLED_PROFILING_MACROS(FOO)
#else
ADD_PREFIX_TO_DISABLED_PROFILING_MACROS(FOO)
#endif
The net result of the above would be to create all the FOO_PROFILE_XXX macros I would have done manually.
Questions:
Is such a helper macro possible?
Is there a better way of achieving what I'm looking for?
I'm happy to use BOOST_PP if necessary.
Before posting this question I tried figuring this out myself, and the code I came up with follows, which may serve to show the road I was going down
#include <stdio.h>
#define PROFILE_START(msg) printf("start(%s)\n", msg);
#define PROFILE_END(msg) printf("end(%s)\n", msg);
#define ENABLE(prefix) \
#define prefix ## _PROFILE_START PROFILE_START \
#define prefix ## _PROFILE_END PROFILE_END
#define DISABLE(prefix) \
#define prefix ## _PROFILE_START \
#define prefix ## _PROFILE_END
#define ENABLE_FOO
#ifdef ENABLE_FOO
ENABLE(FOO)
#else
DISABLE(FOO)
#endif
#ifdef ENABLE_BAR
ENABLE(BAR)
#else
DISABLE(BAR)
#endif
int main()
{
FOO_PROFILE_START("foo");
FOO_PROFILE_END("foo");
BAR_PROFILE_START("bar");
BAR_PROFILE_END("bar");
return 0;
}
Is such a helper macro possible?
No. With the exception of pragmas, you cannot execute a preprocessing directive in a macro.
You can do something very similar using pattern matching. By taking the varying parts out of the macro name, and putting it inside the macro itself, you can make a form that allows enabling/disabling for arbitrary names.
This requires a tiny bit of preprocessor metaprogramming (which is a constant overhead; i.e., doesn't vary as you add modules), so bear with me.
Part 1: A C preprocessor solution
Using this set of macros:
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
#define SWITCH(PREFIX_,PATTERN_,DEFAULT_) SECOND(GLUE(PREFIX_,PATTERN_),DEFAULT_)
#define EAT(...)
#define PROFILER_UTILITY(MODULE_) SWITCH(ENABLE_PROFILER_FOR_,MODULE_,DISABLED)
#define PROFILER_IS_DISABLED ,EAT
#define PROFILE_START_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START)(msg)
#define PROFILE_END_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_END)(msg)
...which you can include in each module, you will gain the ability to do this:
PROFILE_START_FOR(FOO,msg)
PROFILE_END_FOR(FOO,msg)
PROFILE_START_FOR(BAR,msg)
PROFILE_END_FOR(BAR,msg)
PROFILE_START_FOR(BAZ,msg)
PROFILE_END_FOR(BAZ,msg)
All of these macros, by default, expand to nothing; you can change this by defining ENABLE_PROFILER_FOR_xxx for any subset of FOO, BAR, or BAZ to expand to , (or ,ON if that looks better), in which case the corresponding macros will expand (initially, before your own macros come in) to PROFILE_START(msg)/PROFILE_END(msg); and the rest will continue expanding to nothing.
Using the FOO module as an example, you can do this with a "control file": #define ENABLE_PROFILER_FOR_FOO ,ON; the command line: ... -DENABLE_PROFILER_FOR_FOO=,ON; or in a makefile; CFLAGS += -DENABLE_PROFILER_FOR_FOO=,ON.
Part 2a: how it works; the SWITCH macro
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
#define SWITCH(PREFIX_,PATTERN_,DEFAULT_) SECOND(GLUE(PREFIX_,PATTERN_),DEFAULT_)
GLUE here is your typical indirect paste macro (allowing arguments to expand). SECOND is an indirect variadic macro returning the second argument.
SWITCH is the pattern matcher. The first two arguments are pasted together, comprising the pattern. By default, this pattern is discarded; but due to the indirection, if that pattern is an object like macro, and that pattern's expansion contains a comma, it will shift a new second argument in. For example:
#define ORDINAL(N_) GLUE(N_, SWITCH(ORDINAL_SUFFIX_,N_,th))
#define ORDINAL_SUFFIX_1 ,st
#define ORDINAL_SUFFIX_2 ,nd
#define ORDINAL_SUFFIX_3 ,rd
ORDINAL(1) ORDINAL(2) ORDINAL(3) ORDINAL(4) ORDINAL(5) ORDINAL(6)
...will expand to:
1st 2nd 3rd 4th 5th 6th
In this manner, the SWITCH macro behaves analogous to a switch statement; whose "cases" are object-like macros with matching prefixes, and which has a default value.
Note that pattern matching in the preprocessor works with shifting arguments, hence the comma (the main trick being that of discarding unmatched tokens by ignoring an argument, and applying matched tokens by shifting a desired replacement in). Also for the most general case with this SWITCH macro, you need at a minimum to ensure that all PREFIX_/PATTERN_ arguments are pasteable (even if that token isn't seen, it has to be a valid token).
Part 2b: combined switches for safety
A lone switch works like a case statement, allowing you to shove anything in; but when the situation calls for a binary choice (like "enable" or "disable"), it helps to nest one SWITCH in another. That makes the pattern matching a bit less fragile.
In this case, the implementation:
#define PROFILER_UTILITY(MODULE_) SWITCH(ENABLE_PROFILER_FOR_,MODULE_,DISABLED)
#define PROFILER_IS_DISABLED ,EAT
#define PROFILE_START_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START)(msg)
#define PROFILE_END_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_END)(msg)
...uses PROFILER_UTILITY as the inner switch. By default, this expands to DISABLED. That makes the pattern in SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START) by default be PROFILER_IS_DISABLED, which shoves in EAT. In the non-default case of PROFILER_UTILITY, the outer switch kicks in making it expand to PROFILE_START. PROFILE_END_FOR works analogously.
The EAT macro takes (msg) in both cases to nothing; otherwise, the original macro's called.
Is there a better way of achieving what I'm looking for?
Depends on what you're looking for. This approach shows what's possible with the C preprocessor.
I personally would go for something like
#include <stdio.h>
#define FOO_ENABLED 1
#define BAR_ENABLED 0
#define PROFILE_START(FLAG, msg) \
{ if (FLAG) printf("start(%s)\n", msg); }
int main()
{
PROFILE_START(FOO_ENABLED, "foo")
PROFILE_START(BAR_ENABLED, "bar")
return 0;
}
Any decent compiler would not generate any instructions for the if statement anyway.
Is such a helper macro possible?
No. As was covered in comments, you cannot generate macro definitions via macros.*
Is there a better way of achieving what I'm looking for?
Since the macro idea won't work,* any alternative that does work is better. Basically, you're looking for a code generator -- a program that will take as input a list of modules and produce as output C source (maybe a header) containing definitions of all the profiling macros for all the modules. You could write such a program in pretty much any language -- C, python, perl, shell script, whatever. Depending on your technology preferences and project context, you might even go with something like XSLT.
Each source file that wants to get the profiling macros then just #includes the generated header.
*In fact, you could use the C preprocessor, by performing a separate, standalone run on a different, for-purpose input file. But you cannot generate the macros in-place when you compile the source file(s) that wants to use them.

Removing extra parentheses from C++ macro

I have a bunch of source code that uses double-parentheses for a bunch of macro calls where the 2nd arg and forward is a varargs for a print statement.
DEBUG((1,"here is a debug"))
DEBUG((1,"here is %d and %d",42,43))
etc..
I want to write a macro that can print args 2-..., but I can't figure out how to remove the extra parentheses so I can access the args.
I.e., this obviously does not work:
#define DEBUG(ignore,...) fprintf(stderr,__VA_ARGS__)
And the following attempt to be sneaky also fails (with 'DEBUG2 not defined'):
#define DEBUG2(ignore,...) fprintf(stderr,__VA_ARGS__)
#define DEBUG(...) DEBUG2
Without editing all the macro calls to remove parens, how can I define a macro that will do this?
You may do:
#define PRINTF(unused, ...) fprintf(stderr, __VA_ARGS__)
#define DEBUG(arg) PRINTF arg

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