How can I create a macro which defines a variable? - c++
I have a macro to do a version of default arguments:
#define Log_getMacro4(_1, _2, _3, _4, NAME, ...) NAME
#define Log_logWarning4(...) Log_log__("warning", __VA_ARGS__)
#define Log_logWarning3(...) Log_log__("warning", __VA_ARGS__, __LINE__)
#define Log_logWarning2(...) Log_log__("warning", __VA_ARGS__, __FILE__, __LINE__)
#define Log_logWarning1(...) Log_log__("warning", __VA_ARGS__, __PRETTY_FUNCTION__, __FILE__, __LINE__)
#define Log_logWarning(...) Log_getMacro4(__VA_ARGS__, Log_logWarning4, Log_logWarning3, Log_logWarning2, Log_logWarning1)(__VA_ARGS__)
The problem is that I now want to provide a variant on that function which frees the first argument to Log_logWarning after:
#define Log_logWarning_free(str, ...) Log_logWarning(str, __VA_ARGS__); if (str) free(str);
The problem is that this cannot be used with the return value of a function. For example:
char *foo(){
char *ret = (char*)malloc(30*sizeof(char));
strcpy(ret, "Hello World");
return ret;
}
void bar(){
Log_logWarning_free(foo());
}
Therefore, I was wondering if there is a way to create a local variable first to which I will assign the first argument of the macro and then use that variable in the test and subsequent free.
I would use an inline function instead, if at all possible.
If you have to use a macro, use a do { ... } while (0) construct:
#define Log_logWarning_free(str, ...) \
do { \
char * logtmp_ = str; \
Log_logWarning(logtmp_, __VA_ARGS__); \
if (logtmp_) free(logtmp_); \
} while (0)
The do-while-0 trick allows you to have a code block, while it prevents accidentally attaching the block to an another flow control construct incorrectly.
This full test program compiles with 4.7.2:
#include <stdlib.h>
#define Log_logWarning_free(str, ...) \
do { \
char * logtmp_ = str; \
Log_logWarning(logtmp_, __VA_ARGS__); \
if (logtmp_) free(logtmp_); \
} while (0)
void Log_logWarning(char* fmt, ...);
char * get_log_str(void);
int main()
{
Log_logWarning_free(get_log_str(), 1, 2, 3);
return 0;
}
Firstly, wrap your functions in do { } while(0) so you can add a semicolon to your usage of the functions and avoid weird errors.
Secondly, yes, you can use a local variable. See http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html for examples.
An simple example would be
#define swap(a,b) do {int _c=b; b=a; a=_c;} while(0)
That can then be safely invoked as:
int x = 5;
int y = 7;
swap(x, y);
See also: Can a C macro contain temporary variables?
The problem is knowing the type of the variable (except in
C++11). For the rest, you can use the usual trick for scoping:
#define X(y) do { auto CONCAT(_log_tmp_,__LINE__) = (y); ... } while(false);
In C and in C++ pre-C++11, you'll probably have to pass the type
of the variable in as an argument to the macro.
Related
Is it possible to make macros that are default arguments expand at call site?
#include <stdio.h> void print(int a = __LINE__){printf("hello %d\n", a);} void main(){ print(); print(); print(); print(); } The __LINE__ macro in this case expands to 3, so the print function is called 4 times with the same value. Is there a way to convince the compiler to expand this macro at the callsite, so that the print function would be called with 6,7,8,9 instead of 3,3,3,3 with features that exist in C++11? My usecase: In my application, I provide multiple functions that take a unique ID. The ID should be unique per callsite/location (so if the function is called two times throught the same statement, it should receive the same id). Currently, the user always has to manually type a LOCATION macro at the callsite, like this: #define S1(x) #x //voodoo to concat __FILE__ and __LINE__ #define S2(x) S1(x) #define LOCATION __FILE__ S2(__LINE__) do_stuff1(arguments, LOCATION) do_stuff2(arguments, LOCATION) It would be more convenient if I could save them the typing, without creating a macro for each function like this: #define do_stuff1(do_stuff1_imp(arguments, LOCATION)) #define do_stuff2(do_stuff2_imp(arguments, LOCATION)) Hence I thought a default argument would do the trick. Is there any way to achieve this?
You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard: #include <experimental/source_location> void print(std::experimental::source_location const& location = std::experimental::source_location()) { printf("hello %s:%d\n", location.file_name(), location.line()); }
The __LINE__ macro in this case expands to 3 Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there. Another macro instead of a function declaration would do the trick well (taken from #Ejay's comment): #define print() printf("hello %d\n", __LINE__) See a working example here.
You can write a macro which inserts the __FILE__ and __LINE__ into the argument list: // Note: this doesn't work with a 0-argument function. Supporting 0-arg functions // is much harder to do; I'd recommend just having a separate macro like as follows #define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__) #define LOCATED0(fn) fn(__FILE__, __LINE__) void print(char const* file_name, int line) { printf("hello %s:%d\n", file_name, line); } int do_something(int value, char const* file_name, int line); int main() { LOCATED0(print); LOCATED(do_something, 42); } With a little more work, you can make it look nicer at the call-site: #define LOCATED(...) LOCATED_##__VA_ARGS__ void print(char const* file_name, int line) { printf("hello %s:%d\n", file_name, line); } #define LOCATED_print() ::print(__FILE__, __LINE__) int do_something(int value, char const* file_name, int line); #define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__) int main() { LOCATED(print()); LOCATED(do_something(42)); }
Ignoring MACRO argument [duplicate]
Is there some way of getting optional parameters with C++ Macros? Some sort of overloading would be nice too.
Here's one way to do it. It uses the list of arguments twice, first to form the name of the helper macro, and then to pass the arguments to that helper macro. It uses a standard trick to count the number of arguments to a macro. enum { plain = 0, bold = 1, italic = 2 }; void PrintString(const char* message, int size, int style) { } #define PRINT_STRING_1_ARGS(message) PrintString(message, 0, 0) #define PRINT_STRING_2_ARGS(message, size) PrintString(message, size, 0) #define PRINT_STRING_3_ARGS(message, size, style) PrintString(message, size, style) #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 #define PRINT_STRING_MACRO_CHOOSER(...) \ GET_4TH_ARG(__VA_ARGS__, PRINT_STRING_3_ARGS, \ PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, ) #define PRINT_STRING(...) PRINT_STRING_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) int main(int argc, char * const argv[]) { PRINT_STRING("Hello, World!"); PRINT_STRING("Hello, World!", 18); PRINT_STRING("Hello, World!", 18, bold); return 0; } This makes it easier for the caller of the macro, but not the writer.
With great respect to Derek Ledbetter for his answer — and with apologies for reviving an old question. Getting an understanding of what it was doing and picking up elsewhere on the ability to preceed the __VA_ARGS__ with ## allowed me to come up with a variation... // The multiple macros that you would need anyway [as per: Crazy Eddie] #define XXX_0() <code for no arguments> #define XXX_1(A) <code for one argument> #define XXX_2(A,B) <code for two arguments> #define XXX_3(A,B,C) <code for three arguments> #define XXX_4(A,B,C,D) <code for four arguments> // The interim macro that simply strips the excess and ends up with the required macro #define XXX_X(x,A,B,C,D,FUNC, ...) FUNC // The macro that the programmer uses #define XXX(...) XXX_X(,##__VA_ARGS__,\ XXX_4(__VA_ARGS__),\ XXX_3(__VA_ARGS__),\ XXX_2(__VA_ARGS__),\ XXX_1(__VA_ARGS__),\ XXX_0(__VA_ARGS__)\ ) For non-experts like me who stumble upon the answer, but can't quite see how it works, I'll step through the actual processing, starting with the following code... XXX(); XXX(1); XXX(1,2); XXX(1,2,3); XXX(1,2,3,4); XXX(1,2,3,4,5); // Not actually valid, but included to show the process Becomes... XXX_X(, XXX_4(), XXX_3(), XXX_2(), XXX_1(), XXX_0() ); XXX_X(, 1, XXX_4(1), XXX_3(1), XXX_2(1), XXX_1(1), XXX_0(1) ); XXX_X(, 1, 2, XXX_4(1,2), XXX_3(1,2), XXX_2(1,2), XXX_1(1,2), XXX_0(1,2) ); XXX_X(, 1, 2, 3, XXX_4(1,2,3), XXX_3(1,2,3), XXX_2(1,2,3), XXX_1(1,2,3), XXX_0(1,2,3) ); XXX_X(, 1, 2, 3, 4, XXX_4(1,2,3,4), XXX_3(1,2,3,4), XXX_2(1,2,3,4), XXX_1(1,2,3,4), XXX_0(1,2,3,4) ); XXX_X(, 1, 2, 3, 4, 5, XXX_4(1,2,3,4,5), XXX_3(1,2,3,4,5), XXX_2(1,2,3,4,5), XXX_1(1,2,3,4,5), XXX_0(1,2,3,4,5) ); Which becomes just the sixth argument... XXX_0(); XXX_1(1); XXX_2(1,2); XXX_3(1,2,3); XXX_4(1,2,3,4); 5; PS: Remove the #define for XXX_0 to get a compile error [ie: if a no-argument option is not allowed]. PPS: Would be nice to have the invalid situations (eg: 5) be something that gives a clearer compilation error to the programmer! PPPS: I'm not an expert, so I'm very happy to hear comments (good, bad or other)!
With greatest respect to Derek Ledbetter, David Sorkovsky, Syphorlate for their answers, together with the ingenious method to detect empty macro arguments by Jens Gustedt at https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ finally I come out with something that incorporates all the tricks, so that the solution Uses only standard C99 macros to achieve function overloading, no GCC/CLANG/MSVC extension involved (i.e., comma swallowing by the specific expression , ##__VA_ARGS__ for GCC/CLANG, and implicit swallowing by ##__VA_ARGS__ for MSVC). So feel free to pass the missing --std=c99 to your compiler if you wish =) Works for zero argument, as well as unlimited number of arguments, if you expand it further to suit your needs Works reasonably cross-platform, at least tested for GNU/Linux + GCC (GCC 4.9.2 on CentOS 7.0 x86_64) GNU/Linux + CLANG/LLVM, (CLANG/LLVM 3.5.0 on CentOS 7.0 x86_64) OS X + Xcode, (XCode 6.1.1 on OS X Yosemite 10.10.1) Windows + Visual Studio, (Visual Studio 2013 Update 4 on Windows 7 SP1 64 bits) For the lazies, just skip to the very last of this post to copy the source. Below is the detailed explanation, which hopefully helps and inspires all people looking for the general __VA_ARGS__ solutions like me. =) Here's how it goes. First define the user-visible overloaded "function", I named it create, and the related actual function definition realCreate, and the macro definitions with different number of arguments CREATE_2, CREATE_1, CREATE_0, as shown below: #define create(...) MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) void realCreate(int x, int y) { printf("(%d, %d)\n", x, y); } #define CREATE_2(x, y) realCreate(x, y) #define CREATE_1(x) CREATE_2(x, 0) #define CREATE_0() CREATE_1(0) The MACRO_CHOOSER(__VA_ARGS__) part ultimately resolves to the macro definition names, and the second (__VA_ARGS__) part comprises their parameter lists. So a user's call to create(10) resolves to CREATE_1(10), the CREATE_1 part comes from MACRO_CHOOSER(__VA_ARGS__), and the (10) part comes from the second (__VA_ARGS__). The MACRO_CHOOSER uses the trick that, if __VA_ARGS__ is empty, the following expression is concatenated into a valid macro call by the preprocessor: NO_ARG_EXPANDER __VA_ARGS__ () // simply shrinks to NO_ARG_EXPANDER() Ingeniusly, we can define this resulting macro call as #define NO_ARG_EXPANDER() ,,CREATE_0 Note the two commas, they are explained soon. The next useful macro is #define MACRO_CHOOSER(...) CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER __VA_ARGS__ ()) so the calls of create(); create(10); create(20, 20); are actually expanded to CHOOSE_FROM_ARG_COUNT(,,CREATE_0)(); CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER 10 ())(10); CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER 20, 20 ())(20, 20); As the macro name suggests, we are to count number of arguments later. Here comes another trick: the preprocessor only does simple text replacement. It infers the number of arguments of a macro call merely from the number of commas it sees inside the parentheses. The actual "arguments" separated by commas need not to be of valid syntax. They can be any text. That's to say, in the above example, NO_ARG_EXPANDER 10 () is counted as 1 argument for the middle call. NO_ARG_EXPANDER 20 and 20 () are counted as 2 arguments for the bottom call respectively. If we use the following helper macros to further expand them ##define CHOOSE_FROM_ARG_COUNT(...) \ FUNC_RECOMPOSER((__VA_ARGS__, CREATE_2, CREATE_1, )) #define FUNC_RECOMPOSER(argsWithParentheses) \ FUNC_CHOOSER argsWithParentheses The trailing , after CREATE_1 is a work-around for GCC/CLANG, suppressing a (false positive) error saying that ISO C99 requires rest arguments to be used when passing -pedantic to your compiler. The FUNC_RECOMPOSER is a work-around for MSVC, or it can not count number of arguments (i.e., commas) inside the parentheses of macro calls correctly. The results are further resolved to FUNC_CHOOSER (,,CREATE_0, CREATE_2, CREATE_1, )(); FUNC_CHOOSER (NO_ARG_EXPANDER 10 (), CREATE_2, CREATE_1, )(10); FUNC_CHOOSER (NO_ARG_EXPANDER 20, 20 (), CREATE_2, CREATE_1, )(20, 20); As the eagle-eyed you may have seen, the last only step we need is to employ a standard argument counting trick to finally pick the wanted macro version names: #define FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3 which resolves the results to CREATE_0(); CREATE_1(10); CREATE_2(20, 20); and certainly gives us the desired, actual function calls: realCreate(0, 0); realCreate(10, 10); realCreate(20, 20); Putting all together, with some rearrangement of statements for better readability, the whole source of the 2-argument example is here: #include <stdio.h> void realCreate(int x, int y) { printf("(%d, %d)\n", x, y); } #define CREATE_2(x, y) realCreate(x, y) #define CREATE_1(x) CREATE_2(x, 0) #define CREATE_0() CREATE_1(0) #define FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3 #define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses #define CHOOSE_FROM_ARG_COUNT(...) FUNC_RECOMPOSER((__VA_ARGS__, CREATE_2, CREATE_1, )) #define NO_ARG_EXPANDER() ,,CREATE_0 #define MACRO_CHOOSER(...) CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER __VA_ARGS__ ()) #define create(...) MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) int main() { create(); create(10); create(20, 20); //create(30, 30, 30); // Compilation error return 0; } Although complicated, ugly, burdening the API developer, there comes a solution for overloading and setting optional parameters of C/C++ functions to us crazy people. The usage of the out-coming overloaded APIs become very enjoyable and pleasant. =) If there is any further possible simplification of this approach, please do let me know at https://github.com/jason-deng/C99FunctionOverload Again special thanks to all of the brilliant people that inspired and led me to achieve this piece of work! =)
C++ macros haven't changed from C. Since C didn't have overloading and default arguments for functions, it certainly didn't have them for macros. So to answer your question: no, those features don't exist for macros. Your only option is to define multiple macros with different names (or not use macros at all). As a sidenote: In C++ it's generally considered good practice to move away from macros as much as possible. If you need features like this, there's a good chance you're overusing macros.
For anyone painfully searching some VA_NARGS solution that works with Visual C++. Following macro worked for me flawlessly(also with zero parameters!) in visual c++ express 2010: #define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,N,...) N #define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple #define VA_NARGS(...) bool(#__VA_ARGS__) ? (VA_NUM_ARGS_IMPL_((__VA_ARGS__, 24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1))) : 0 If you want a macro with optional parameters you can do: //macro selection(vc++) #define SELMACRO_IMPL(_1,_2,_3, N,...) N #define SELMACRO_IMPL_(tuple) SELMACRO_IMPL tuple #define mymacro1(var1) var1 #define mymacro2(var1,var2) var2*var1 #define mymacro3(var1,var2,var3) var1*var2*var3 #define mymacro(...) SELMACRO_IMPL_((__VA_ARGS__, mymacro3(__VA_ARGS__), mymacro2(__VA_ARGS__), mymacro1(__VA_ARGS__))) That worked for me aswell in vc. But it doesn't work for zero parameters. int x=99; x=mymacro(2);//2 x=mymacro(2,2);//4 x=mymacro(2,2,2);//8
gcc/g++ supports varargs macros but I don't think this is standard, so use it at your own risk.
More concise version of Derek Ledbetter's code: enum { plain = 0, bold = 1, italic = 2 }; void PrintString(const char* message = NULL, int size = 0, int style = 0) { } #define PRINT_STRING(...) PrintString(__VA_ARGS__) int main(int argc, char * const argv[]) { PRINT_STRING("Hello, World!"); PRINT_STRING("Hello, World!", 18); PRINT_STRING("Hello, World!", 18, bold); return 0; }
#include <stdio.h> #define PP_NARG(...) \ PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) #define PP_NARG_(...) \ PP_ARG_N(__VA_ARGS__) #define PP_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _61,_62,_63,N,...) N #define PP_RSEQ_N() \ 63,62,61,60, \ 59,58,57,56,55,54,53,52,51,50, \ 49,48,47,46,45,44,43,42,41,40, \ 39,38,37,36,35,34,33,32,31,30, \ 29,28,27,26,25,24,23,22,21,20, \ 19,18,17,16,15,14,13,12,11,10, \ 9,8,7,6,5,4,3,2,1,0 #define PP_CONCAT(a,b) PP_CONCAT_(a,b) #define PP_CONCAT_(a,b) a ## b #define THINK(...) PP_CONCAT(THINK_, PP_NARG(__VA_ARGS__))(__VA_ARGS__) #define THINK_0() THINK_1("sector zz9 plural z alpha") #define THINK_1(location) THINK_2(location, 42) #define THINK_2(location,answer) THINK_3(location, answer, "deep thought") #define THINK_3(location,answer,computer) \ printf ("The answer is %d. This was calculated by %s, and a computer to figure out what this" " actually means will be build in %s\n", (answer), (computer), (location)) int main (int argc, char *argv[]) { THINK (); /* On compilers other than GCC you have to call with least one non-default argument */ } DISCLAIMER: Mostly harmless.
As a big fan of horrible macro monsters, I wanted to expand on Jason Deng's answer and make it actually usable. (For better or worse.) The original is not very nice to use because you need to modify the big alphabet soup every time you want to make a new macro and it's even worse if you need different amount of arguments. So I made a version with these features: 0 argument case works 1 to 16 arguments without any modifications to the messy part Easy to write more macro functions Tested in gcc 10, clang 9, Visual Studio 2017 Currently I just made 16 argument maximum, but if you need more (really now? you're just getting silly...) you can edit FUNC_CHOOSER and CHOOSE_FROM_ARG_COUNT, then add some commas to NO_ARG_EXPANDER. Please see Jason Deng's excellent answer for more details on the implementation, but I'll just put the code here: #include <stdio.h> void realCreate(int x, int y) { printf("(%d, %d)\n", x, y); } // This part you put in some library header: #define FUNC_CHOOSER(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, ...) _f16 #define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses #define CHOOSE_FROM_ARG_COUNT(F, ...) FUNC_RECOMPOSER((__VA_ARGS__, \ F##_16, F##_15, F##_14, F##_13, F##_12, F##_11, F##_10, F##_9, F##_8,\ F##_7, F##_6, F##_5, F##_4, F##_3, F##_2, F##_1, )) #define NO_ARG_EXPANDER(FUNC) ,,,,,,,,,,,,,,,,FUNC ## _0 #define MACRO_CHOOSER(FUNC, ...) CHOOSE_FROM_ARG_COUNT(FUNC, NO_ARG_EXPANDER __VA_ARGS__ (FUNC)) #define MULTI_MACRO(FUNC, ...) MACRO_CHOOSER(FUNC, __VA_ARGS__)(__VA_ARGS__) // When you need to make a macro with default arguments, use this: #define create(...) MULTI_MACRO(CREATE, __VA_ARGS__) #define CREATE_0() CREATE_1(0) #define CREATE_1(x) CREATE_2(x, 0) #define CREATE_2(x, y) \ do { \ /* put whatever code you want in the last macro */ \ realCreate(x, y); \ } while(0) int main() { create(); create(10); create(20, 20); //create(30, 30, 30); // Compilation error return 0; }
That's not really what the preprocessor is designed for. That said, if you want to enter into the area of seriously challenging macro programming with a modicum of readability, you should take a look at the Boost preprocessor library. After all, it wouldn't be C++ if there weren't three completely Turing compatible levels of programming (preprocessor, template metaprogramming, and base level C++)!
#define MY_MACRO_3(X,Y,Z) ... #define MY_MACRO_2(X,Y) MY_MACRO(X,Y,5) #define MY_MACRO_1(X) MY_MACRO(X,42,5) You know at the point of call how many args you're going to pass in so there's really no need for overloading.
You can use BOOST_PP_OVERLOAD from a boost library. Example from official boost doc: #include <boost/preprocessor/facilities/overload.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/facilities/empty.hpp> #include <boost/preprocessor/arithmetic/add.hpp> #define MACRO_1(number) MACRO_2(number,10) #define MACRO_2(number1,number2) BOOST_PP_ADD(number1,number2) #if !BOOST_PP_VARIADICS_MSVC #define MACRO_ADD_NUMBERS(...) BOOST_PP_OVERLOAD(MACRO_,__VA_ARGS__)(__VA_ARGS__) #else // or for Visual C++ #define MACRO_ADD_NUMBERS(...) \ BOOST_PP_CAT(BOOST_PP_OVERLOAD(MACRO_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY()) #endif MACRO_ADD_NUMBERS(5) // output is 15 MACRO_ADD_NUMBERS(3,6) // output is 9
Depending on what you need, you could do it with var args with macros. Now, optional parameters or macro overloading, there is no such thing.
Not directly answering the question, but using the same trick as David Sorkovsky answer and giving a clear example of how to build complex macros. Just compile this with g++ -E test.cpp -o test && cat test: // #define GET_FIRST_ARG_0_ARGS(default) (default) // #define GET_FIRST_ARG_1_ARGS(default, a) (a) // #define GET_FIRST_ARG_2_ARGS(default, a, b) (a) // #define GET_FIRST_ARG_3_ARGS(default, a, b, c) (a) // #define GET_FIRST_ARG_4_ARGS(default, a, b, c, d) (a) #define GET_FIRST_ARG_MACROS(default, a, b, c, d, macro, ...) macro #define GET_FIRST_ARG(default, ...) GET_FIRST_ARG_MACROS( \ ,##__VA_ARGS__, \ GET_FIRST_ARG_4_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_3_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_2_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_1_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_0_ARGS(default, ##__VA_ARGS__), \ ) "0,"; GET_FIRST_ARG(0); "0,1"; GET_FIRST_ARG(0,1); "0,1,2"; GET_FIRST_ARG(0,1,2); "0,1,2,3"; GET_FIRST_ARG(0,1,2,3); "0,1,2,3,4"; GET_FIRST_ARG(0,1,2,3,4); To see the output: # 1 "test.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/x86_64-linux-gnu/include/stdc-predef.h" 1 3 # 1 "<command-line>" 2 # 1 "test.cpp" # 16 "test.cpp" "0,"; GET_FIRST_ARG_0_ARGS(0); "0,1"; GET_FIRST_ARG_1_ARGS(0, 1); "0,1,2"; GET_FIRST_ARG_2_ARGS(0, 1,2); "0,1,2,3"; GET_FIRST_ARG_3_ARGS(0, 1,2,3); "0,1,2,3,4"; GET_FIRST_ARG_4_ARGS(0, 1,2,3,4); Now, a full working program would be: #include <iostream> #define GET_FIRST_ARG_0_ARGS(default) (default) #define GET_FIRST_ARG_1_ARGS(default, a) (a) #define GET_FIRST_ARG_2_ARGS(default, a, b) (a) #define GET_FIRST_ARG_3_ARGS(default, a, b, c) (a) #define GET_FIRST_ARG_4_ARGS(default, a, b, c, d) (a) #define GET_FIRST_ARG_MACROS(default, a, b, c, d, macro, ...) macro #define GET_FIRST_ARG(default, ...) GET_FIRST_ARG_MACROS( \ ,##__VA_ARGS__, \ GET_FIRST_ARG_4_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_3_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_2_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_1_ARGS(default, __VA_ARGS__), \ GET_FIRST_ARG_0_ARGS(default, ##__VA_ARGS__), \ ) int main(int argc, char const *argv[]) { "0,"; GET_FIRST_ARG(0); "0,1"; GET_FIRST_ARG(0,1); "0,1,2"; GET_FIRST_ARG(0,1,2); "0,1,2,3"; GET_FIRST_ARG(0,1,2,3); "0,1,2,3,4"; GET_FIRST_ARG(0,1,2,3,4); std::cerr << "0, == " << GET_FIRST_ARG(0) << std::endl; std::cerr << "0,1 == " << GET_FIRST_ARG(0,1) << std::endl; std::cerr << "0,1,2 == " << GET_FIRST_ARG(0,1,2) << std::endl; std::cerr << "0,1,2,3 == " << GET_FIRST_ARG(0,1,2,3) << std::endl; std::cerr << "0,1,2,3,4 == " << GET_FIRST_ARG(0,1,2,3,4) << std::endl; return 0; } Which would output the following by being compiled with g++ test.cpp -o test && ./test: 0, == 0 0,1 == 1 0,1,2 == 1 0,1,2,3 == 1 0,1,2,3,4 == 1 Note: It is important to use () around the macro contents as #define GET_FIRST_ARG_1_ARGS(default, a) (a) to not break in ambiguous expressions when a is just not a integer. Extra macro for second argument: #define GET_SECOND_ARG_0_ARGS(default) (default) #define GET_SECOND_ARG_1_ARGS(default, a) (default) #define GET_SECOND_ARG_2_ARGS(default, a, b) (b) #define GET_SECOND_ARG_3_ARGS(default, a, b, c) (b) #define GET_SECOND_ARG_4_ARGS(default, a, b, c, d) (b) #define GET_SECOND_ARG_MACROS(default, a, b, c, d, macro, ...) macro #define GET_SECOND_ARG(default, ...) GET_SECOND_ARG_MACROS( \ ,##__VA_ARGS__, \ GET_SECOND_ARG_4_ARGS(default, __VA_ARGS__), \ GET_SECOND_ARG_3_ARGS(default, __VA_ARGS__), \ GET_SECOND_ARG_2_ARGS(default, __VA_ARGS__), \ GET_SECOND_ARG_1_ARGS(default, __VA_ARGS__), \ GET_SECOND_ARG_0_ARGS(default, ##__VA_ARGS__), \ )
None of the above examples (from Derek Ledbetter, David Sorkovsky, and Joe D) to count arguments with macros worked for me using Microsoft VCC 10. The __VA_ARGS__ argument is always considered as a single argument (token-izing it with ## or not), so the argument shifting in which those examples rely doesn't work. So, short answer, as stated by many others above: no, you can't overload macros or use optional arguments on them.
Iterate a preprocessor macro on a list of class names
I would like to run macros on a list of class names to avoid copy/pasting errors and hassle. Imagine, as a simple example, that every class in my SDK needs to call a static allocation method before it is used. So, every time I add a new class, I have to manually add the following line at initialization: MyNewClass::allocate(); And I also need to do the same for initialization and destruction. So, instead of doing this manually every time, I was wondering if there was a way to write a list of all my class names somewhere, then define a macro to call the corresponding methods for each class in the list. Something in the lines of: #define ALLOCATE( TheClass ) TheClass ## ::allocate(); But instead of just passing TheClass as an argument, I'd like to pass a list of my classes. So by calling: ALLOCATE_ALL( ClassA, ClassB, ClassC ) it would expand to: ClassA::allocate(); ClassB::allocate(); ClassC::allocate(); Ultimately, I would like to be able to define a class list and have multiple macros iterate over it. Something in the lines of: ALLOCATE_ALL( MyClassList ) INIT_ALL( MyClassList ) DESTROY_ALL( MyClassList ) I've already taken a look at variadic macros but, if I understand the concept correctly, you have to define as many macros as the final number of arguments; and that is simply not viable in my case. Is this possible at all? Thanks for any help and/or feedback.
If you are satisfied with having one list of classes, you can use the following trick: #define MY_CLASSES X(ClassA) X(ClassB) X(ClassC) Then you can do something like: #define X(a) a::allocate(); MY_CLASSES #undef X To do something else, you can do: #define X(a) a::init(); MY_CLASSES #undef X
You could use a variadic function template : #include <iostream> // Thanks to Jarod42 for improving it ! template <class... TClasses> void allocateAll() { std::initializer_list<int>{(TClasses::allocate(), void(), 0)...}; } struct C1 { static void allocate() { std::cout << "allocated C1\n"; } }; struct C2 { static void allocate() { std::cout << "allocated C2\n"; } }; struct C3 { static void allocate() { std::cout << "allocated C3\n"; } }; int main() { allocateAll<C1, C2, C3>(); return 0; } Outputs : allocated C1 allocated C2 allocated C3 The functions are called in the same order that you pass their classes in. You can also centralize the classes list : // Use a template instead of a function so you can typedef it template <class... TClasses> struct ClassesList { static void allocateAll() { std::initializer_list<int>{(TClasses::allocate(), void(), 0)...}; } // Add any other utilities here private: ClassesList(); }; // Declare your list using MyClassesList = ClassesList<C1, C2, C3>; int main(int, char**) { // Just as before MyClassesList::allocateAll(); }
To improve slightly the answer given by LindyLancer suggesting X-macros you could have a seperate file // file my_classes.def #ifndef MY_CLASS #error MY_CLASS should be defined before including my_classes.def MY_CLASS(ClassA) MY_CLASS(ClassB) /// etc... #undef MY_CLASS Then you would include that several times, e.g. #define MY_CLASS(Classname) class Classname; #include "my_classes.def" and later, inside some initializer (or your main) #define MY_CLASS(Classname) Classname::init(); #include "my_classes.def"
Using Boost.Preprocessor : #include <boost/preprocessor/seq/for_each.hpp> #define MyClassList \ (ClassA) \ (ClassB) \ (ClassC) #define ALLOCATE_ALL( R, DATA, ELEM ) \ ELEM :: allocate(); #define INIT_ALL( R, DATA, ELEM ) \ ELEM :: init(); //... BOOST_PP_SEQ_FOR_EACH( ALLOCATE_ALL, _, MyClassList ) BOOST_PP_SEQ_FOR_EACH( INIT_ALL, _, MyClassList )
You can define a generic macro that iterates, but the one time definition of it is ugly. This is because you do need one macro definition for each argument, up to the max number of nesting levels supported by your compiler (I believe the minimum is at least 63, but GCC is only limited by available memory). But since it is generic, you may find other uses of it. For up to 5, a possible implementation is: #define M_ITER(M, ...) \ M_ITER_(__VA_ARGS__, _5, _4, _3, _2, _1)(M, __VA_ARGS__) #define M_ITER_(_1, _2, _3, _4, _5, X, ...) M_ITER ## X #define M_ITER_1(M, X) M(X) #define M_ITER_2(M, X, ...) M(X) M_ITER_1(M, __VA_ARGS__) #define M_ITER_3(M, X, ...) M(X) M_ITER_2(M, __VA_ARGS__) #define M_ITER_4(M, X, ...) M(X) M_ITER_3(M, __VA_ARGS__) #define M_ITER_5(M, X, ...) M(X) M_ITER_4(M, __VA_ARGS__) This is basically how BOOST_PP_SEQ_FOR_EACH is implemented. And then, you could use it for your purpose like this: #define ALLOCATE_ALL(...) M_ITER(ALLOCATE, __VA_ARGS__) #define INIT_ALL(...) M_ITER(INIT, __VA_ARGS__) #define DESTROY_ALL(...) M_ITER(DESTROY, __VA_ARGS__) ALLOCATE_ALL(ClassA, ClassB, ClassC) INIT_ALL(ClassA, ClassB, ClassC) DESTROY_ALL(ClassA, ClassB, ClassC)
The accepted answer by Lindydancer is unsatisfactory to me because it relies on repeatedly redefining the X macro, which seems mysterious on use and could lead to collisions. Instead, I prefer a variation that accepts the name of the macro as a parameter: #define FOR_EACH_CLASS(macro) \ macro(ClassA) \ macro(ClassB) \ macro(ClassC) This would be used liked like: #define CALL_ALLOCATE(classname) classname::allocate(); FOR_EACH_CLASS(CALL_ALLOCATE) #undef CALL_ALLOCATE /* optional undef */ There is another answer to a related question: Real-world use of X-Macros that gives more examples of the technique. (Note that, in that question, the accepted answer once again relies on redefining a macro with a particular name, whereas the one I linked accepts the macro name as a parameter.)
Passing variable name as string to function with default parameters
Let’s say there is a debugging function, simplified here as: void DumpString(char* var, char* varname) { printf("%s : '%s'\n", varname, var); } char str[10]="foobar"; DumpString(str, "str"); > str : foobar Let’s make it easier by removing the unnecessarily extraneous requirement of passing the variable twice, once in quotes: #define VARASSTR(v) #v void DumpString(char* var) { printf("%s : '%s'\n", VARASSTR(var), var); } char str[10]="foobar"; DumpString(str); > var : foobar Oops! It uses the local variable name instead of the one passed in. Let’s try a different (and less ideal) tack: #define DumpStr(v) DumpString(v, #v) void DumpString(char* var, char* varname) { printf("%s : '%s'\n", varname, var); } char str[10]="foobar"; DumpStr(str); > str : foobar Great it works. But what if the function was a little more complicated: void DumpString(char* var, char* varname, int optionalvar=0) { printf("%s : '%s'\n", varname, var); printf("blah: %d", optionalvar); } It is not possible to overload a macro, so DumpStr won’t work, and we have already ruled out the version with VARASSTR. How can this be handled (without resorting to multiple similarly, but differently-named functions/macros)?
This is non-standard, but works as an extension in GNU C: #define DumpStr(v, ...) DumpString(v, #v, ##__VA_ARGS__) In GNU C, you can pass no arguments to a variadic macro, and the "token pasting operator" ## when applied between a comma and an empty variadic argument list produces nothing (so the trailing comma is suppressed). In Visual C++, I believe the token pasting operator ## is unnecessary (and will probably break the macro), as Visual C++ automatically suppresses a trailing comma if it appears before an empty variadic argument list. Note that the only thing that makes this nonstandard is the desire to sometimes pass an empty argument list. Variadic macros are standardized in both C99 and C++11. Edit: And here's an example that doesn't use non-standard features. You can see why some people really, really wish this sort of thing was addressed in the standard: #define DUMPSTR_1(v) DumpString(v, #v) #define DUMPSTR_2(v, opt) DumpString(v, #v, opt) #define DUMPSTR_NARG(...) DUMPSTR_ARG_N(__VA_ARGS__, 4, 3, 2, 1, 0) #define DUMPSTR_ARG_N(_1, _2, _3, _4, n, ...) n #define DUMPSTR_NC(f, ...) f(__VA_ARGS__) #define DUMPSTR_NB(nargs, ...) DUMPSTR_NC(DUMPSTR_ ## nargs, __VA_ARGS__) #define DUMPSTR_NA(nargs, ...) DUMPSTR_NB(nargs, __VA_ARGS__) #define DumpStr(...) DUMPSTR_NA(DUMPSTR_NARG(__VA_ARGS__), __VA_ARGS__) There's probably a few cleaner ways to do this. But not that many. Edit 2: And here's yet another example that doesn't use non-standard features, courtesy of R.. #define STRINGIFY_IMPL(s) #s #define STRINGIFY(s) STRINGIFY_IMPL(s) #define ARG1_IMPL(a, ...) a #define ARG1(...) ARG1_IMPL(__VA_ARGS__, 0) #define DumpStr(...) DumpString(STRINGIFY(ARG1(__VA_ARGS__)), __VA_ARGS__) Note that this requires the argument order of the DumpString to be changed so that the stringified function name is the first argument.
Syntax Error in Preprocessor Macro Code
I am trying to write some code for a macro which returns the length of a string, and am attempting to implement it using BOOST_PP_WHILE. The code stems from the fact that a character at a position specified by position of the string represented by a macro argument foo may be obtained by #foo[position]. Compiling using either MSVC or Intel C++ results in similar syntax errors; if you could point out why the code is generating these syntax errors and how I would rectify code, it would be greatly appreciated. I know that the errors are caused by the code within the PREDICATE macro, but any expression I attempt to use within it barring BOOST_PP_TUPLE_ELEM results in a compile-time error. Errors: prog.cpp:47:1: error: pasting "BOOST_PP_BOOL_" and ""\"Hello, World!\""" does not give a valid preprocessing token prog.cpp: In function ‘int main(int, char**)’: prog.cpp:47: error: ‘BOOST_PP_TUPLE_ELEM_2_1’ was not declared in this scope As one would expect, the line numbers are not very useful since both point to the line at which the macro MACRO_STRLEN is called. Code Below follows the source listing in which I attempt to implement the macro which I describe. #include <boost/preprocessor/arithmetic/dec.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/comparison/equal.hpp> #include <boost/preprocessor/control/while.hpp> #include <boost/preprocessor/tuple/elem.hpp> #include <cstdio> #define TEST_STRING0 "Hello, World!" #define MACRO_IS_NULL_IMPL(x, position) \ #x[position] == '\0' #define MACRO_IS_NULL(x, position) \ MACRO_IS_NULL_IMPL(x, position) #define PREDICATE_D(string, position) \ MACRO_IS_NULL(string, position) #define PREDICATE(n, state) \ PREDICATE_D( \ BOOST_PP_TUPLE_ELEM(2, 0, state), \ BOOST_PP_TUPLE_ELEM(2, 1, state) \ ) #define OPERATION_D(string, position) \ ( \ string, \ BOOST_PP_INC(position) \ ) #define OPERATION(d, state) \ OPERATION_D( \ BOOST_PP_TUPLE_ELEM(2, 0, state), \ BOOST_PP_TUPLE_ELEM(2, 1, state) \ ) #define MACRO_STRLEN_IMPL(string) \ BOOST_PP_TUPLE_ELEM( \ 2, 1, BOOST_PP_WHILE(PREDICATE, OPERATION, (string, 0)) \ ) #define MACRO_STRLEN(string) \ MACRO_STRLEN_IMPL(string) int main(int argc, char ** argv) { printf("String length: %d.\n", MACRO_STRLEN(TEST_STRING0)); return 0; }
How about this - http://codepad.org/aT7SK1Lu Its still a compile-time strlen, and would be likely much faster to compile. #include <stdio.h> #include <string.h> #define TEST_STRING "Hello, World!" template <int N> struct xtmp2 { typedef char (&t)[N]; }; template< class T, int N > typename xtmp2<N>::t xlen( T (&)[N] ); #define STRLEN(x) (sizeof(xlen(x))-1) int main( void ) { printf( "strlen(\"%s\") = %i %i\n", TEST_STRING, STRLEN(TEST_STRING), strlen(TEST_STRING) ); } As to macro debug, its possible to get a preprocessor output (like gcc -E); it may be also helpful to undefine most macros, then enable them one by one to see what happens.
Please forgive me if this is an irrelevant pointing out. The predicate for BOOST_PP_WHILE is evaluated while preprocess. However, if I understand correctly, MACRO_IS_NULL_IMPL determines whether the character is '\0' at compile-time(runtime?). So, I think it is difficult to accomplish the goal directly with string literal "Hello, World!".
It won't work, and for a simple reason: the preprocessor is not meant to deal with literals. The preprocessor only knows about "tokens", it can catenate them, it can transform one into a string literal, and it can operate macros replacements, but that's it. Here, the condition to stop the loop (use of [] and ==) could be, at best, executed by the compiler (and most likely at runtime), therefore is not suitable for BOOST_PP_WHILE. You can, actually, use the compiler to get the number of elements of an array (here an array of characters): For example using sizeof: sizeof(array)/sizeof(array[0]). This can be abstracted in a macro, however it cannot become a "regular" function, since arrays cannot be passed to "regular" functions, only pointers (where you've lost the information size). You can also use a template function: template <typename T, size_t N> size_t size(T (&)[N]) { return N; } (this actually work on any array with a constant size) But, for your own issue, you'll be pleased to know that most compilers have a built-in strlen implementation for constants that evaluates at compile-time.
I wonder if it was supposed to be something like this: #include <stdio.h> #include <string.h> #define TEST_STRING "Hello, World!" #define STRLEN(x) (x[0]==0)?0:TEST_01(x,1) #define TEST_01(x,y) (x[y]==0)?y:TEST_02(x,y+1) #define TEST_02(x,y) (x[y]==0)?y:TEST_03(x,y+1) #define TEST_03(x,y) (x[y]==0)?y:TEST_04(x,y+1) #define TEST_04(x,y) (x[y]==0)?y:TEST_05(x,y+1) #define TEST_05(x,y) (x[y]==0)?y:TEST_06(x,y+1) #define TEST_06(x,y) (x[y]==0)?y:TEST_07(x,y+1) #define TEST_07(x,y) (x[y]==0)?y:TEST_08(x,y+1) #define TEST_08(x,y) (x[y]==0)?y:TEST_09(x,y+1) #define TEST_09(x,y) (x[y]==0)?y:TEST_10(x,y+1) #define TEST_10(x,y) (x[y]==0)?y:TEST_11(x,y+1) #define TEST_11(x,y) (x[y]==0)?y:TEST_12(x,y+1) #define TEST_12(x,y) (x[y]==0)?y:TEST_13(x,y+1) #define TEST_13(x,y) (x[y]==0)?y:TEST_14(x,y+1) #define TEST_14(x,y) (x[y]==0)?y:TEST_15(x,y+1) #define TEST_15(x,y) (x[y]==0)?y:TEST_16(x,y+1) #define TEST_16(x,y) (x[y]==0)?y:TEST_17(x,y+1) #define TEST_17(x,y) (x[y]==0)?y:TEST_18(x,y+1) #define TEST_18(x,y) (x[y]==0)?y:TEST_19(x,y+1) #define TEST_19(x,y) (x[y]==0)?y:-1 int main( void ) { printf( "strlen(\"%s\") = %i %i\n", TEST_STRING, STRLEN(TEST_STRING), strlen(TEST_STRING) ); } But this isn't a compile-time evaluation, even though it would be usually optimized to a constant.