The following iterator macro is given to me (cannot change)
#define ITERATE(MACRO) \
MACRO(v1) \
MACRO(v2) \
MACRO(v3) \
MACRO(v4)
The idea behind this is that I can now define my own one-argument macro and pass it into the iterator to expand for v1, v2, v3, v4. For example:
#define MYSTUFF(X) doSth(X);
ITERATE(MYSTUFF)
will expand to
doSth(v1); doSth(v2); doSth(v3); doSth(v4);
My current problem is that I want to invoke ITERATE within another macro which would like to pass an extra argument into MYSTUFF beyond one provided by the ITERATE.
To achieve that I was hoping that I could capture the extra parameter name with the following construct:
#define PARTIAL(T) FULL(UUU,T)
#define FULL(U,V) doSth(U,V)
#define START(UUU) ITERATE(PARTIAL)
START(bla)
I was hoping that when ITERATE(PARTIAL) is expanded to:
FULL(UUU,v1) FULL(UUU,v2) FULL(UUU,v3) FULL(UUU,v4)
I will actually capture the UUU parameter of START and it will be replaced by bla. Unfortunately that is not the case (at least in gcc).
Do you know if such name capturing can be achieved differently?
Or perhaps you have a different idea how to solve the problem of passing extra parameter into MACRO?
I may be permitted to change ITERATOR definition itself but only if it doesn't break any existing code already using it.
You can't do it this way. Your START() macro basically takes a single argument, which it then discards.
What you can do is define UUU where you need it, eg.
#define PARTIAL(T) FULL(UUU,T)
#define FULL(U,V) doSth(U,V)
#define START() ITERATE(PARTIAL)
// ...
#define UUU blah
START()
#undef UUU
Your problem, simplified, looks like this:
#define FOO UUU
#define START(UUU) FOO
START(5)
Here's what happens:
macro START is encountered in line START(5)
START is a function-like macro, so it becomes expanded with argument UUU=5):
stage 1 (argument expansion): macro arguments are macro-expanded
Nothing happens, 5 is not a macro.
Body: FOO
stage 2 (argument prescan): macro arguments are substituted into the macro body.
Nothing happens, UUU is not in the body.
Body: FOO
stage 3 (expansion): the body is macro-expanded again
FOO gets expanded into UUU, which is not a macro.
Body: UUU
I can't think of any clever way to expand FOO inside the body before the argument prescan happens. I don't think it's possible to do what you want directly.
Go with #Hasturkun's workaround and make UUU a macro, not a parameter.
Related
Background
I am working on an existing codebase which uses a macro pattern to generate boilerplate methods similar to this:
START_MAP()
MAP_ENTRY(a)
MAP_ENTRY(b)
// .....
MAP_ENTRY(z)
END_MAP()
I am re-implementing the code that these macros generate, but I can not touch this pattern because that would require large refactors. I need to expand this pattern into a macro (which I define) which we will call NEW_IMPLEMENT which is a variadic macro that is called like so: NEW_IMPLEMENT(a, b, ..., z).
Problem
How can I redefine START_MAP, MAP_ENTRY, and END_MAP so that the pattern as it currently exists expands to NEW_IMPLEMENT(a, b, ..., z)?
What I have tried so far
#define NEW_IMPLEMENT(...) ...
#define START_MAP NEW_IMPLEMENT(
#define MAP_ENTRY(x) x,
#define END_MAP )
This throws a preprocessor error, however: error: unterminated argument list invoking macro "NEW_IMPLEMENT"
You can make the pattern expand to NEW_IMPLEMENT(stuff) text, but the resulting macro will not be expanded - C preprocessor does not rescan results from multiple macro expansions together.
You can "join" them, by wrapping everything in another macro call which will force another pass over all the results. And also you need to pass the paren as a token, not literally, so that you don't get unterminated call.
#define CALL(...) __VA_ARGS__
#define PAREN (
#define START_MAP() NEW_IMPLEMENT PAREN
#define END_MAP() )
#define MAP_ENTRY(a) a,
#define NEW_IMPLEMENT(...) "Hello: " #__VA_ARGS__
CALL(
START_MAP()
MAP_ENTRY(a)
MAP_ENTRY(b)
// .....
MAP_ENTRY(z)
END_MAP()
)
But overall, I do not understand. I would prefer to refactor the code with a simple sed 's/START_MAP()/NEW_IMPLEMENT(/; s/MAP_ENTRY(a)/a,/; s/END_MAP()/)/' for code readability and maintainability. I do not think "not touching ancient code" is a good enough reason for making the codebase more convoluted.
I want to have a macro MAC(...) which expands to all except the first argument passed to it. How do I achieve this?
My first thoughts were to convert the __VA_ARGS__ to a BOOST_PP_TUPLE and then do a POP_FRONT operation:
#define MAC(...)\
BOOST_PP_TUPLE_POP_FRONT(BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
MAC(1,2,3)
But this simply expands to
BOOST_PP_TUPLE_POP_FRONT((1,2,3))
I tried adding the BOOST_PP_EXPAND macro:
#define MAC(...)\
BOOST_PP_EXPAND(\
BOOST_PP_TUPLE_POP_FRONT BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
MAC(1,2,3)
But I get the same result. What I want is an output of
2, 3
How do I achieve this?
Using templates is not an option nor is using other libraries or tools (other than boost).
Have you tried the simple answer?
#define Y(ignore, ...) __VA_ARGS__
#define X(...) Y(__VA_ARGS__)
Let's say I have defined a macro which does this
#define MY_MACRO(NAME) \
std::string get##NAME() const \
{ \
return doSomething(#NAME); \
}
Where doSomething method signature will be something like this
std::string doSomething(const std::string& parameter);
This works pretty well when the NAME macro parameter has no dashes in it.
For example :
#define MY_MACRO(thisIsA_test) // Works
But, when I have a dash in my string (this can happen) it won't work because dashes are not allowed in method names
#define MY_MACRO(thisIsA-test) // does NOT WORK
I have tried to work it around this way
#define thisIsAtest "thisIsA-test"
#define MY_MACRO(thisIsAtest)
Everything compiles just fine and I have the getthisIsAtest method generated but unfortunately the macro is not resolved and "thisIsAtest" is kept as string literal.
In other words the doSomething parameter string value will be "thisIsAtest" whereas I was expecting "thisIsA-test".
To expand the macro argument, just use an indirection macro.
#define stringize_literal( x ) # x
#define stringize_expanded( x ) stringize_literal( x )
Your use-case:
return doSomething( stringize_expanded( NAME ) );
Now the method will be named with name of the macro, and the function will be called with the contents of the macro. Somewhat questionable in terms of organization, but there you have it.
Why it works:
By default, macro arguments are expanded before being substituted. So if you pass thisIsAtest to parameter NAME, the macro expansion will replace NAME with "thisIsA-test". The pre-expansion step does not apply when you use a preprocessor operator # or ## though.
In your original code, one use of NAME is subject to ## and the other is subject to # so the macro definition of thisIsAtest never gets used. I just introduced a macro stringize_expanded which introduces an artificial use of NAME (via x) which is not subject to an operator.
This is the idiomatic way to use # and ##, since the expansion is desired more often than the literal macro name. You do happen to want the default behavior for ## in this case, but it could be considered a case of poor encapsulation (as the name of an interface is used to produce output), if you wanted to apply real programming principles to the problem.
There's nothing to work around.
As you have said yourself, dashes are not valid in function names.
So, do not use them.
I try to get at the first actual parameter sent to a variadic macro. This is what I tried, and which does not work in VS2010:
#define FIRST_ARG(N, ...) N
#define MY_MACRO(...) decltype(FIRST_ARG(__VA_ARGS__))
When I look at the preprocessor output I see that FIRST_ARG returns the entire argument list sent to MY_MACRO...
On the other hand when I try with:
FIRST_ARG(1,2,3)
it expands to 1 as intended.
This seems to be somehow the inverse of the problem solved by the infamous two level concat macros. I know that "macro parameters are fully expanded before inserted in the macro body" but this does not seem to help me here as I don't understand what this means in the context of ... and __VA_ARGS__
Obviously __VA_ARGS__ binds to N and is only evaluated later. I tried several ways with extra macro levels but it didn't help.
This is a bug in the Visual C++ preprocessor. The workaround listed there works. This:
#define FIRST_ARG_(N, ...) N
#define FIRST_ARG(args) FIRST_ARG_ args
#define MY_MACRO(...) decltype(FIRST_ARG((__VA_ARGS__)))
MY_MACRO(x, y, z)
expands to:
decltype(x)
I'm reading the phoneME's source code. It's a FOSS JavaME implementation. It's written in C++, and I stumbled upon this:
// Makes a string of the argument (which is not macro-expanded)
#define STR(a) #a
I know C and C++, but I never read something like this. What does the # in #a do?
Also, in the same file, there's:
// Makes a string of the macro expansion of a
#define XSTR(a) STR(a)
I mean, what's the use of defining a new macro, if all it does is calling an existing macro?
The source code is in https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. You can find it with a CTRL+F.
In the first definition, #a means to print the macro argument as a string. This will turn, e.g. STR(foo) into "foo", but it won't do macro-expansion on its arguments.
The second definition doesn't add anything to the first, but by passing its argument to another macro, it forces full macro expansion of its argument. So XSTR(expr) creates a string of expr with all macros fully expanded.
# is the stringizing operator. The preprocessor makes a string out of the parameter.
Say you have:
STR(MyClass);
It would be preprocessed as:
"MyClass";
The level of indirection (using XSTR()) has to do with macro expansion rules.
First, you should know that this pair of macros is actually fairly common. The first does exactly what the comment says -- it turns an argument into a string by enclosing it in double quotes.
The second is used to cause macro expansion of the argument. You typically use them together something like this:
#define a value_a
printf("%s", XSTR(a));
The macro expansion will expand a out to string_a, and the stringify will turn that into a string, so the output will be value_a.
The #a is referred to as the stringizer operator. It takes the formal parameter, in this case a, and turns it in to a string by enclosing it in double quotes.
So if you have:
string s = STR("my quoted string");
cout << s;
The output would be:
"my quoted string"