c++ Macro Overloading is not working - c++

I am trying to overload a c++ preprocessor macro depending on the number of arguments..
For example, I want to do this:
FOO(1, 2, 3) //==> expandsto FOO3(1,2,3)
FOO(1, 2) //==> expandsto FOO2(1,2)
This is what I've done:
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__)
#define FOO2(A, B) std::cout<<"2 arguments"<<std::endl;
#define FOO3(A, B, C) std::cout<<"3 arguments"<<std::endl;
int main() {
FOO(1,2,3)
return 0;
}
In VC++, however, the exact code above gives me a compiler error:
expected a ";"
What did I do wrong..?
UPDATE:
In fact, I realized this works on Ideone >>>LINK<<<... It doesn't work on Visual Studio 12..
Why is this.. and if VS doesn't support this type of macro overloading.. what are the alternatives..?
Thanks

this is VC++ Bugs of __VA_ARGS__
try this
#define ID(x) x
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define FOO(...) ID(GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__))

Looks like it's Visual studio bug, your code is valid (I can compile it with GCC). But it's bad style anyway.
#define FOO2(A, B) std::cout<<"2 arguments"<<std::endl; // add `do {...} while (0)` construction
#define FOO3(A, B, C) std::cout<<"3 arguments"<<std::endl;
int main() {
FOO(1,2,3) // Put `;` here
return 0;
}
Code should look like this:
#define FOO2(A, B) do {std::cout<<"2 arguments"<<std::endl;} while (0)
#define FOO3(A, B, C) do {std::cout<<"3 arguments"<<std::endl;} while (0)
int main() {
FOO(1,2,3); // Looks like normal function now!
return 0;
}
What is that do {} while (0) thing, you may ask? It prevents programmers from using your macro like this: FOO2(1, 2) << "text";.

Related

C++ macro time arithmetic

I'm working on a wgl loader and typedef'd each openGL function that I use like this:
/*Let's say I'm defining n functions*/
typedef return_t (*f1)(params)
f1 _glFunc1;
#define glFunc1(params) _glFunc1(params)
...
typedef return_t (*fn)(params)
fn _glFuncn;
#define glFuncn(params) _glFuncn(params)
Then to get the definitions of these functions I have to use wglGetProcAddress or GetProcAddress and then cast the result to f1, f2 ...
I tried to automate the casting with this macro:
#define GetFuncDef(glFunc) _##glFunc = (f##(__LINE__ - startingLineNumber + 1))GetProcAddress(#glFunc)
Where startingLineNumber is the first line that I use this macro in(in my case it's 22),
but the preprocessor does not compute __LINE__ - startingLineNumber.
Is there some way to force it to do so?
EDIT:
startingLineNumber isn't a variable, macro etc. It's written out as a literal number in my code. like this:
#define GetFuncDef(glFunc) _##glFunc = (f##(__LINE__ - 22 + 1))GetProcAddress(#glFunc), where 22 would be startingLineNumber
Similar to C Preprocessor output int at Build first you have to implement operations:
typedef return_t (*f1)(params)
typedef return_t (*f2)(params)
void *GetProcAddress(charr *);
#define SUB_10_0 10
#define SUB_10_1 9
#define SUB_10_2 8
// etc. for each each possible combination, 1000 of lines ...
#define SUB_21_20 1
// etc. for each each possible combination, 1000 of lines ...
#define SUB_IN(a, b) SUB_##a##_##b
#define SUB(a, b) SUB_IN(a, b)
#define CONCAT_IN(a, b) a##b
#define CONCAT(a, b) CONCAT_IN(a, b)
#define startingLineNumber 20
#define GetFuncDef(glFunc) (CONCAT(f, SUB(__LINE__, startingLineNumber)))GetProcAddress(#glFunc)
int main() {
f1 a = GetFuncDef();
}
Then gcc -E outputs:
typedef return_t (*f1)(params)
typedef return_t (*f2)(params)
void *GetProcAddress(charr *);
int main() {
f1 a = (f1)GetProcAddress("");
}
In a similar fashion mentioned here Boost and P99 libraries can be used.

How to ensure (at compile time) that two macros are called in succession?

I am currently working on a feature that raised a peculiarly difficult problem.
I have two macros :
#define FOO(A) do { /*...*/ } while(0)
#define FOO_END(A) do { /*...*/ } while(0)
What FOO actually does is that it tests values (in a very peculiar way), and FOO_END prints all the test results to the standard output. The detailed content is not publicated here because it's non-modifiable.
Each one of them have several inputs (not just "A"), but I limited it to one for simplicity.
These two macros are made to be used as this: several FOO macros are to be called in succession, then the FOO_END macro needs to be called at the end. I need to ensure that no "functionnal" code is called between the first and the last test (so the values all are coherent).
Example :
int main()
{
// stuff...
FOO(1);
FOO(2);
FOO_END(3);
// stuff...
FOO(4);
FOO_END(5);
// stuff...
return 0;
}
Thus, the following code must fail to compile :
int main()
{
FOO(1);
bar(); // a random function
FOO(2);
FOO_END(3);
return 0;
}
How can I redefine my macros in order to have this feature?
Constraints
The error must be seen at compile time. I already have a version that raises an error at runtime, but it's not enough for me.
FOO and FOO_END must be macros. It's because I need to use
__LINE__ and __FILE__ within them.
C++11 is OK but I would prefer a C++03 solution. If it's possible of course.
No external libraries, if possible. I have very low flexibility on the project I need it for. However, if no native solution is possible, I am still curious.
If you use a start macro you can start an unfinished sentence in it
#define FOO_START uselessFOOFunction(
#define FOO ); do { /*...*/ } while(0); uselessFOOFunction(
#define FOO_END ); do { /*...*/ } while(0)
static void uselessFOOFunction(){}
So this will work :
int main()
{
// stuff...
FOO_START
FOO
FOO
FOO_END;
// stuff...
FOO_START
FOO
FOO_END;
// stuff...
return 0;
}
And this will fail to compile :
int main()
{
FOO_START
FOO
bar(); // a random function
FOO
FOO_END;
return 0;
}
If you also add a FOO_START macro at the start, you could generate a code which will fail to compile with various errors for incorrect examples.
The downside is that the error message won't be about the use of the foo - it will be about the incorrect language constructs the macro expansions generate. You also won't be able to use local variables.
Because of this, I would say that in this form it is unusable, but maybe you could modify it to your use case - this is similar to how some unit test frameworks are implemented.
Here's a simple example:
#include <iostream>
#define CONCAT(A,B) A ## B
#define ST_NAME(N) CONCAT(ST_, N)
#define NP_NAME(N) CONCAT(NP_, N)
#define np_NAME(N) CONCAT(np_, N)
#define MEM_NAME(N) CONCAT(mem_, N);
// NPs are helper structs that ensure that no data members are declared outside the FOO macros
#define NP_START struct NP_NAME(__LINE__) { int i;
#define NP_END } np_NAME(__LINE__); static_assert(sizeof(np_NAME(__LINE__)) == sizeof(int));
#define FOO_START struct { NP_START
#define FOO NP_END struct ST_NAME(__LINE__) { ST_NAME(__LINE__)() { std::cout << "hack!" << std::endl; } } MEM_NAME(__LINE__); NP_START
#define FOO_END NP_END } MEM_NAME(__LINE__);
void bar();
int main() {
int i;
FOO_START;
FOO;
i = 5; // error
int j = bar(); // error
FOO;
bar(); // error
FOO_END;
return 0;
}
With this, you generate an anonymous local struct, and the code will be executed by its constructor.
Edit: fixed the issue mentioned by a comment. Static_assert requires C++11, or boost for 03.
You can't do it using the macros you've proposed. There's no way to ensure no code exists between your macro statements. You can change your approach, though.
Create a macro, DO_FOO, that takes a number N which is the number of times to do FOO. The DO_FOO automatically expands to FOO N times and a single FOO_END. Example:
#define DO_FOO_IMPL_1 FOO; FOO_END
#define DO_FOO_IMPL_2 FOO; DO_FOO_IMPL_1;
#define DO_FOO_IMPL_3 FOO; DO_FOO_IMPL_2;
#define DO_FOO_IMPL_4 FOO; DO_FOO_IMPL_3;
// ... and so on, up to some maximum number N
#define DO_FOO(N) DO_FOO_IMPL_ ## N
Then you use it like this:
int main()
{
// stuff...
DO_FOO(2);
// stuff...
DO_FOO(1);
// stuff...
return 0;
}
My approach would be this: if you don't want people calling arbitrary code between calls to FOO and FOO_END, then put all the FOO calls into a single FOO_LIST call which calls all of them and then calls FOO_END implicitly. That way the rule is enforced by the macro syntax itself.
i.e. instead of:
FOO(1);
FOO(2);
FOO(3);
FOO_END;
have your program do this:
FOO_LIST(1, 2, 3);
... which will be expanded by the preprocessor to into FOO(1); FOO(2); FOO(3); FOO_END();
Here's an example implementation that supports up to 5 arguments in a FOO_LIST; it can be extended if you need more.
#include <stdio.h>
#define FOO(x) do {printf("foo(%i)!\n", x);} while(0)
#define FOO_END do {printf("foo_end!\n\n");} while(0)
// Support up to 5 FOO calls in a FOO_LIST, for now (can be extended as necessary)
#define FOO_LIST_1(f1) {FOO(f1); FOO_END;}
#define FOO_LIST_2(f1, f2) {FOO(f1); FOO(f2); FOO_END;}
#define FOO_LIST_3(f1, f2, f3) {FOO(f1); FOO(f2); FOO(f3); FOO_END;}
#define FOO_LIST_4(f1, f2, f3, f4) {FOO(f1); FOO(f2); FOO(f3); FOO(f4); FOO_END;}
#define FOO_LIST_5(f1, f2, f3, f4, f5) {FOO(f1); FOO(f2); FOO(f3); FOO(f4); FOO(f5); FOO_END;}
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define FOO_LIST(...) GET_MACRO(__VA_ARGS__, FOO_LIST_5, FOO_LIST_4, FOO_LIST_3, FOO_LIST_2, FOO_LIST_1)(__VA_ARGS__)
int main(int,char **)
{
printf("Some functional code here...\n");
FOO_LIST(1);
printf("Some more functional code here...\n");
FOO_LIST(1, 2);
printf("Some more functional code here...\n");
FOO_LIST(1, 2, 3);
return 0;
}

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.

Replacing open bracket character in a C/C++ macro

I need a macro to pass the __FILE__ and __LINE__ to a function which has default arguments. This has opened up a can of worms, since default args with macros are either not possible or very messy, and I need to support both GCC and MSVC if possible:
class Class
{
#ifdef _DEBUG
int Function(int a, int b = 10, int c = 20) { return a + b + c; }
#else
int DebugFunction(const char* filename, int lineNo, int a, int b = 10, int c = 20)
{
printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
return a + b + c;
}
//Not possible
#define Function( DebugFunction(__FILE__, __LINE__
#endif
}
I've tried \escaping the ( to no avail. The codebase is huge, so fixing up the missing default args or creating multiple macros isn't a popular option.
Any solutions?
You can make a variadic macro:
#define Function(...) DebugFunction(__FILE__, __LINE__, __VA_ARGS__)
Since you cannot "overload" macros, this might be your best bet.
One option would be to rewrite your main function Function like this:
int Function(const char* filename, int lineNo, int a, int b = 10, int c = 20)
{
#ifdef _DEBUG
printf("%s (%i) a:%i b:%i c:%i\n", filename, lineNo, a, b, c);
#endif
return a + b + c;
}
That way, all the calls go to the same function, but the behavior of that function depends on whether or not you have the _DEBUG flag set. This bypasses the issue of default arguments, since you just have a normal function call with conditional code inclusion rather than a macro that might need many arguments.
Hope this helps!
I'm not quite sure I understand what you're trying to do, but would a variadic macro do the trick?
Not a big c++ guy, but have you tried something like (in pseudocode)
#ifdef debug
#define Function(args) _Function(__file__, __line__, (args))
int _Function(char *file, int line, args) { /* code */ }
#else
#define Function(args) _Function(args)
int _Function(args) { /* code */ }
#endif
The function itself needs to be able to take multiple versions of arguments, of course; I don't really see any other way of doing this.

BOOST_STATIC_ASSERT without boost

Since boost is forbidden in a company I work for I need to implement its functionality in pure C++. I've looked into boost sources but they seem to be too complex to understand, at least for me. I know there is something called static_assert() in the C++0x standart, but I'd like not to use any C++0x features.
One other trick (which can be used in C) is to try to build an array with a negative size if the assert fail:
#define ASSERT(cond) int foo[(cond) ? 1 : -1]
as a bonus, you may use a typedef instead of an object, so that it is usable in more contexts and doesn't takes place when it succeed:
#define ASSERT(cond) typedef int foo[(cond) ? 1 : -1]
finally, build a name with less chance of name clash (and reusable at least in different lines):
#define CAT_(a, b) a ## b
#define CAT(a, b) CAT_(a, b)
#define ASSERT(cond) typedef int CAT(AsSeRt, __LINE__)[(cond) ? 1 : -1]
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
int main() {
StaticAssert< (4>3) >(); //OK
StaticAssert< (2+2==5) >(); //ERROR
}
Here is my own implementation of static assertions extracted from my code base: Pre-C++11 Static Assertions Without Boost.
Usage:
STATIC_ASSERT(expression, message);
When the static assertion test fails, a compiler error message that somehow contains the STATIC_ASSERTION_FAILED_AT_LINE_xxx_message is generated.
message has to be a valid C++ identifier, like no_you_cant_have_a_pony which will produce a compiler error containing:
STATIC_ASSERTION_FAILED_AT_LINE_1337_no_you_cant_have_a_pony :)
#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
#define CONCATENATE2(arg1, arg2) arg1##arg2
/**
* Usage:
*
* <code>STATIC_ASSERT(expression, message)</code>
*
* When the static assertion test fails, a compiler error message that somehow
* contains the "STATIC_ASSERTION_FAILED_AT_LINE_xxx_message" is generated.
*
* /!\ message has to be a valid C++ identifier, that is to say it must not
* contain space characters, cannot start with a digit, etc.
*
* STATIC_ASSERT(true, this_message_will_never_be_displayed);
*/
#define STATIC_ASSERT(expression, message)\
struct CONCATENATE(__static_assertion_at_line_, __LINE__)\
{\
implementation::StaticAssertion<static_cast<bool>((expression))> CONCATENATE(CONCATENATE(CONCATENATE(STATIC_ASSERTION_FAILED_AT_LINE_, __LINE__), _), message);\
};\
typedef implementation::StaticAssertionTest<sizeof(CONCATENATE(__static_assertion_at_line_, __LINE__))> CONCATENATE(__static_assertion_test_at_line_, __LINE__)
// note that we wrap the non existing type inside a struct to avoid warning
// messages about unused variables when static assertions are used at function
// scope
// the use of sizeof makes sure the assertion error is not ignored by SFINAE
namespace implementation {
template <bool>
struct StaticAssertion;
template <>
struct StaticAssertion<true>
{
}; // StaticAssertion<true>
template<int i>
struct StaticAssertionTest
{
}; // StaticAssertionTest<int>
} // namespace implementation
STATIC_ASSERT(true, ok);
STATIC_ASSERT(false, ko);
int main()
{
return 0;
}
You could simply copy the macro from the Boost source file to your own code. If you don't need to support all the compilers Boost supports you can just pick the right definition for your compiler and omit the rest of the #ifdefs in that file.
I believe this should work:
template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true>{};
#define STATIC_ASSERT(e) (CompileTimeAssert <(e) != 0>())
I am using the following header file, with code ripped from someone else...
#ifndef STATIC_ASSERT__H
#define STATIC_ASSERT__H
/* ripped from http://www.pixelbeat.org/programming/gcc/static_assert.html */
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/* These can't be used after statements in c89. */
#ifdef __COUNTER__
/* microsoft */
#define STATIC_ASSERT(e) enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
#else
/* This can't be used twice on the same line so ensure if using in headers
* that the headers are not included twice (by wrapping in #ifndef...#endif)
* Note it doesn't cause an issue when used on same line of separate modules
* compiled with gcc -combine -fwhole-program. */
#define STATIC_ASSERT(e) enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
#endif
/* http://msdn.microsoft.com/en-us/library/ms679289(VS.85).aspx */
#ifndef C_ASSERT
#define C_ASSERT(e) STATIC_ASSERT(e)
#endif
#endif