I am using the X macro pattern to keep a bunch of arrays/items in sync, and I want to create an argument list from it, however I can't work out a way to get a well formed list. Here's what I mean:
#define MY_DATA \
X(var_one, e_one, 1) \
X(var_two, e_two, 2) \
X(var_three, e_three, 3) \
#define X(a,b,c) b,
enum MyNumbers {
MY_DATA
};
#undef X
#define X(a,b,c) c,
int MyValues[] = {
MY_DATA
};
#undef X
void my_func(int a, int b, int c) {} // example do-nothing proc
void main(void)
{
int var_one = MyValues[e_one];
int var_two = MyValues[e_two];
int var_three = MyValues[e_three];
#define X(a,b,c) a,
my_func(MY_DATA); // this fails because of the trailing comma
#undef X
}
Macros are not really my forte, so I can't think of a way of getting rid of the final comma in the function call. Can anyone think of a way to stop it?
Look at the Boost Preprocessor library for “preprocessor metaprogramming tools including repetition and recursion.”
Even if you don't use their complete package, the chapter I linked to explains some techniques, specifically including iteration to build data structures and statements.
Here's an idea: write
my_func(MY_DATA 0);
and declare my_func to take an extra (ignored) argument.
void my_func(int a, int b, int c, int)
I use a variant of this pattern frequently. However, it is normally used to define mappings between data. Along the lines of this:
MESSAGE(10, "Some error message"),
MESSAGE(11, "Som other error message"),
What des not make sense in your approach is that typically these constructs are used for large numbers of entries (100s, 1000s). You normally do not want that many arguments to a function.
If you really want to follow the approach, you could add another MACRO
#define MY_DATA \
X(var_one, e_one, 1) COMMA \
X(var_two, e_two, 2) COMMA \
X(var_three, e_three, 3) \
and define comma as needed when you define X. (Or you could just put the comma in directly).
Here is an option:
void my_func(int a, int b, int c, int dummy) {}
// ...
my_func(MY_DATA 0);
If you can't change my_func then make a thunk (i.e. an intermediate function that calls my_func)
A second option would be to include the comma in the MY_DATA macro instead of in X:
#define MY_DATA \
X(var_one, e_one, 1), \
X(var_two, e_two, 2), \
X(var_three, e_three, 3)
Related
Is it possible to prefix each element of variadic parameters with something else?
#define INPUTS(...) ???
Function(INPUTS(a, b, c))
should become
Function(IN a, IN b, IN c)
Take a look at Boost.Preprocessor.
While daunting, it can be used to do all kinds of weird things, like exactly this:
#include <boost/preprocessor.hpp>
#define MAKE_IN_ARG(r,_,arg) (IN arg)
#define ARGS(...) \
BOOST_PP_SEQ_TO_TUPLE( \
BOOST_PP_SEQ_FOR_EACH(MAKE_IN_ARG,, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))
void f ARGS( int a, float b, char c )
{
//...
}
Produces:
void f (IN int a, IN float b, IN char c )
{
}
That said...
You are making a mistake. Don’t do this. Just type out the IN in front of every input argument when you write the function header. Your life will be significantly easier.
In the class there are a lot of methods with similar implementation, only method's name and argument-list different:
void function1 (int a, bool b)
{
mMember->function1(a, b);
}
void function2 (double a, string b)
{
mMember->function2(a, b);
}
It is required to replace all them with variadic macro.
Something like this
#define MYMACRO(funcname, ...) void funcname (__VA_ARGS__) { mMember->funcname (__VA_ARGS__)}
but it is generated into such call
mMember->function1(int a, bool b)
And of course gives compilation errors.
How can parameters' values be got inside macro, so that to pass them into mMember->funcname without types?
mMember->function1(a, b)
How can parameters' values be got inside macro, so that to pass them into mMember->funcname without types?
It is not possible. The typical solution is to pass types and variables in separate arguments and have two separate chains of expansions. This will not work without typedef for function types or array types.
// Macro overloading on number of arguments left for the reader.
// This is a static example for 4 arguments.
#define MYMACRO_ARGS(a, b, c, d) a b, c d
#define MYMACRO_PARAM(a, b, c, d) b, d
#define MYMACRO(funcname, ...) \
void funcname(MYMACRO_ARGS(__VA_ARGS__)) { \
mMember->funcname(MYMACRO_PARAM(__VA_ARGS__)); \
}
MYMACRO(function2, double, a, string, b)
Overall, I recommend not doing it. Hiding your code behind a macro will make your code harder to read and maintain. Strongly consider just writing the stuff out, instead of making it very hard for linters, code analyzers, and programmers and confusing yourself with unreadable error messages from the compiler.
I have been trying to use variadic macros to reduce redundant code in some SFINAE patterns I am using. Specifically, I would like to generate function definitions using variadic macros. (This question is not about SFINAE). For my application, I would like write a wrapper function that calls an existing member function. The actual application requires that I produce a templated struct with SFINAE specialization so there is some repetitive stuff that would be great to just have a macro take care of generating the struct and function. OK that is the motivation.
The following example dispenses with all of the SFINAE stuff and simply defines a struct with three static functions (f0, f1, f2) with different parameter lists, and tries to call these functions through global macro generated function. Why would you want to do this?? You wouldn't. But this is just to illustrate the problem that I was having for the SFINAE application.
#include<iostream>
struct Foo
{
static void f0()
{
std::cout<<"f0() called"<<std::endl;
}
static void f1(int a)
{
std::cout<<"f1("<<a<<") called"<<std::endl;
}
static double f2(int a, double b)
{
std::cout<<"f2("<<a<<","<<b<<") called"<<std::endl;
return a*b;
}
};
#define VA_LIST(...) __VA_ARGS__
#define FUNCTION_WRAPPER(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME(PARAMS)\
{\
return Foo::NAME(ARGS);\
}
FUNCTION_WRAPPER(f0,void,VA_LIST(),VA_LIST())
FUNCTION_WRAPPER(f1,void,VA_LIST(int a),VA_LIST(a))
FUNCTION_WRAPPER(f2,double,VA_LIST(int a, double b), VA_LIST(a, b))
int main()
{
f0();
f1(1);
f2(1,4.2);
return 0;
}
OK. So the VA_LIST(...) __VA_ARGS__ enables the creation of a single variable list. The call:
FUNCTION_WRAPPER(f2,double,VA_LIST(int a, double b), VA_LIST(a, b))
utilizes to variable lists as argument 3 and 3. Note that the Parameter list and the Argument list have to be consistent with each other (i.e. variables passed in the Argument list better be declared in the Parameter list.
This seems to work for this example, although there are issues if we were to try to add an fixed argument to beginning of the call (e.g. Foo::NAME(fixedArg, ARGS) ). It appears that the ##__VA_ARGS trick to swallow the comma if the variable list is empty doesn't work with this approach.
So the questions I have is:
While this approach seems to work properly on both gcc and clang, I can't find any similar examples that uses multiple variable lists in this manner...which makes me a little nervous. Is this a valid approach?
So what is actually happening in this approach? How is the FUNCTION_WRAPPER macro able to handle two variable lists? Are the PARAMS and ARGS macro arguments simply being expanded in the body of the macro, or is there something more complex happening here?
Is there a way to use the ## trick to swallow preceding commas? Placing the ## preceding the PARAMS and ARGS values in the macro body result in a compilation error, as does placing the ## in the VA_LIST.
Sample code for this last case is:
#define VA_LIST2(...) __VA_ARGS__
#define FUNCTION_WRAPPER2(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME##_2(PARAMS)\
{\
return Foo::NAME(1,ARGS);\
}
FUNCTION_WRAPPER2(f2,double,VA_LIST2(double b), VA_LIST2(b))
The error for the insertion of ## into the FUNCTION_WRAPPER body is
error: pasting "," and "VA_LIST" does not give a valid preprocessing token
return Foo::NAME(1,##ARGS);\
The compilation error for the insertion of ## into the VA_LIST macro body is:
error: '##' cannot appear at either end of a macro expansion
#define VA_LIST2(...) ##__VA_ARGS__
^
How is the FUNCTION_WRAPPER macro able to handle two variable lists?
C preprocessor first recognizes arguments of a macro, then expands the arguments, then replaces the body of the macro with the expansion of arguments.
Because macro arguments are first "recognized" before expanded, macro expansion inside arguments resulting in a comma doesn't change the count of arguments.
Is there a way to use the ## trick to swallow preceding commas?
Be aware that it is still a GNU extension. Standard alternative to GCC's ##__VA_ARGS__ trick?
Yes, just make them to VA_ARGS so you can ## them.
#define VA_LIST2(...) __VA_ARGS__
#define ADD_ONE(...) 1,##__VA_ARGS__
#define FUNCTION_WRAPPER2(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME##_2(PARAMS)\
{\
return Foo::NAME(ADD_ONE(ARGS));\
}
FUNCTION_WRAPPER2(f2,double,VA_LIST2(), VA_LIST2())
FUNCTION_WRAPPER2(f2,double,VA_LIST2(double b), VA_LIST2(b))
Is this a valid approach?
Sure, it's great. I would drop VA_LIST from the call. Lists in preprocessor are just done with (...). Then, just apply VA_LIST on the (...) argument.
#define VA_LIST(...) __VA_ARGS__
#define FUNCTION_WRAPPER(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME(VA_LIST PARAMS) \
{ \
return Foo::NAME(VA_LIST ARGS); \
}
FUNCTION_WRAPPER(f0,void,(),())
FUNCTION_WRAPPER(f1,void,(int a),(a))
FUNCTION_WRAPPER(f2,double,(int a, double b), (a, b))
#define ADD_ONE(...) 1,##__VA_ARGS__
#define FUNCTION_WRAPPER2(NAME,RTYPE,PARAMS,ARGS)\
RTYPE NAME##_2(VA_LIST PARAMS) \
{ \
return Foo::NAME(ADD_ONE ARGS); \
}
FUNCTION_WRAPPER2(f2,double,(), ())
FUNCTION_WRAPPER2(f2,double,(double b), (b))
Anyway, double b .... b you are repeating yourself, however it is very clean and very flexible. You might want to see How to use variadic macro arguments in both a function definition and a function call? , c++ variadic macro: how to retrieve arguments values where I'm passing types and variable names as separate tokens and splitting them later differently depending on if it's function parameter list or call parameters.
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
The above line is take from Unreal 4, and I know I could ask it over on the unreal forums, but I think this is a general C++ question that warrants being asked here.
I understand the first line defines a macro, however I am not well versed in preprocessor shenanigans in C++ and so I'm lost over there. Logic tells me the backslash means the declaration continues onto the next line.
FThreadSafeStaticStat looks a bit like a template, but there's #'s going on in there and a syntax I've never seen before in C++
Could someone tell me what this means? I understand that you may not have access to Unreal 4, but it's just the syntax I don't understand.
## is the preprocessor operator for concatenation.
So if you use
DEFINE_STAT(foo)
anywhere in the code, it gets replaced with
struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;
before your code is compiled.
Here is another example from a blog post of mine to explain this further.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Stumped?\n");
}
This program would compile and execute successfully, and produce the following output:
Stumped?
When the preprocessor is invoked on this code,
begin is replaced with decode(a,n,i,m,a,t,e)
decode(a,n,i,m,a,t,e) is replaced with m ## a ## i ## n
m ## a ## i ## n is replaced with main
Thus effectively, begin() is replaced with main().
TLDR; ## is for concatenation and # is for stringification (from cppreference).
The ## concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo accepts a function argument as its 1st argument and the operators a and b as the 2nd and 3rd arguments:
#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)
int main(int argc, char **argv) {
int a = 2;
int b = 3;
printf("%d+%d=%d\n", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
return 0;
}
The # concatenates the parameter and encloses the output in quotes. The example is:
#include <stdio.h>
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
bar(1, "x", int); // 1, "x", int
return 0;
}
Suppose I have a macro defined as this:
#define FOO(x,y) \
do {
int a,b;
a = f(x);
b = g(x);
y = a+b;
} while (0)
When expanding the macro, does GCC "guarantee" any sort of uniqueness to a,b? I mean in the sense that if I use FOO in the following manner:
int a = 1, b = 2;
FOO(a,b);
After, preprocessing this will be:
int a = 1, b = 2;
do {
int a,b;
a = f(a);
b = g(b);
b = a+b;
} while (0)
Can/will the compiler distinguish between the a outside the do{} and the a inside the do? What tricks can I use to guarantee any sort of uniqueness (besides making the variables inside have a garbled name that makes it unlikely that someone else will use the same name)?
(Ideally functions would be more useful for this, but my particular circumstance doesn't permit that)
If we consider scoping of variables, it is guaranteed that a,b inside the do..while() will be different from the ones defined outside.
For your case, the a,b defined outside will not exist inside the do..while().
There are lots of things to watch out for when using MACROs.
Macros perform just string substitution. The semantic is low and the the compiler have a limited knowledge of the preprocessor (essentially #pragma which in fact is not a preprocessor keyword, and source line info).
In your case a and b are not initialized local value. Behavior is unpredictible.
Your expanded code is equivalent to the following one.
int a = 1, b = 2;
do {
int a___,b___;
a___ = f(a___);
b___ = g(b___);
b___ = a___+b___;
} while (0)
To avoid such case in c++ prefer the use of inline function or template.
If you use a c 1999 compliant compiler, you can use inline in c language.
http://en.wikipedia.org/wiki/Inline_function
In c you can make safer macro by defining longer variable and surrounding parameter by () :
#define FOO(x,y) \
do {
int FOO__a,FOO__b;
FOO__a = f(x);
FOO__b = g(x);
y = FOO__a+FOO__b + (y)*(y);
} while (0)
Note : I changed your example by adding a (y)*(y) to illustrate the case
It is also a good practice to use only once macro parameter.
This prevent side effects like that:
#define max(a,b) a>b?a:b
max(i++,--y)
Max will not return what you want.
Variables a and b are treated just as any local variables inside a local scope.
The C language guarantees that if those variables happen to have the same names as outer scope variables, the local variables will be the ones updated.
Here is an example to illustrate:
#include <stdio.h>
#define FOO(x) \
{ \
int a; \
a = x; \
printf("%d\n", a); \
}
int main()
{
int a = 1;
{
int a = 2;
printf("%d\n", a); // 2
FOO(3); // 3
printf("%d\n", a); // 2
}
printf("%d\n", a); // 1
getchar();
}
Now, of course it might be a bright idea to not name every single variable in your program "a" just because C guarantees that local variables take precedence. But technically there is nothing stopping you from it.
Btw MISRA-C bans naming like this, it require each variable no matter scope to have an unique name, for readability and maintenance reasons.
(As a sidenote, function-like macros is incredibly poor programming style and shouldn't be used. Use real functions instead, and inline them if performance is critical.)
There is no tricks other than garbling. The C and C++ preprocessors do not have the equivalent of lisp gensym or hygienic macros.
Nope, there is no guarantee of uniqueness.
Infact, your code is about to fail.
Macros are just like replacement of text.
I usually use crazy variable names if I am inside a macro, like this:
#define FOO(x,y) \
do {
int FOO_MACRO_a, FOO_MACRO_b;
FOO_MACRO_a = f(x);
FOO_MACRO_b = g(x);
y = FOO_MACRO_a + FOO_MACRO_b;
} while (0)
If you are targeting gcc and/or g++ then you can use their special macro block feature:
#define max(x, y) ({ typeof(x) a_ = (x); \
typeof(y) b_ = (y); \
(a_ > b_) ? a_ : b_ })
This allows you to create unique local variables, very much the same as writing a function.
Of course, for portability, it's not recommended. On the other hand, if you only plan to work on systems that offer gcc/g++, it will work on all of those.
Source: http://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC30
Further, with gcc / g++ you can use the -Wshadow command line option. In the event you inadvertently reuse a local variable with the same name, it will warn you. You can further use -Werror to transform those warnings in error. Now you can't compile if there is the possibility of a mixed up variable. You need to make sure to use a block, though. A do/while() as others have presented would do the job.
int a;
// code from macro;
do { int a = 5; ... } while(false);
With the combo I just described (-Wshadow + -Werror), you get an error when you do int a = 5.
You can actually make sure that regardless of what x and y are you won't have this problem by doing the following:
#define FOO(x,y) \
do\
{\
int x##y##a,x##y##b;\
x##y##a = f(x);\
x##y##b = g(x);\
y = x##y##a + x##y##b;\
} while (0)
By making sure a and b names contains x and y names you know they are different. But that's a really bad code and you probably shouldn't code like this.
Macros are textually expanded as is, modulo parameter replacement, so there's nothing the compiler can do to provide the sort of guarantee you're asking for -- as you can see in the expansion, the a parameter will refer to the inner a, not the outer one. The solution is indeed to use "garbled" names, e.g. int FOO_a, FOO_b;
In your macro that is indeed a danger and so is the possible reuse of x which is not guaranteed to be an l-value and could change by being used in the macro twice.
Even if you do need a macro, it can still be a light wrapper around an inline function, and one such that will take x and give you both f(x) and g(x) without possibly having to re-evaluate x would certainly be safe.
In your case something like:
template< typename T >
struct Foo
{
T& x;
explicit Foo(T&x_) : x(x_)
{
}
int f();
int g();
};
template<typename T>
Foo<T> makeFoo(T& x)
{
return Foo<T>(x);
}
#define FOO(x,y)
{
Foo FOO_VAR(x);
y = FOO_VAR.f() + FOO_VAR.g();
}
would be a safer way to do things. Of course if you don't need the macro at all, do away with it.