I have a macro which is supposed to take a function name and a list of function parameters as arguments and generate a function from that:
#include <iostream>
#include <string>
#include <array>
#define COMMA ,
#define DEFINE_FUNC(funcName,parameters,impl) \
void funcName(parameters) impl
DEFINE_FUNC(
test_func, /* function name */
float f COMMA float f2, /* Parameters */
{
std::cout<<f<<","<<f2<<std::endl;
} /* Implementation */
)
int main()
{
test_func(1.f,2.f);
}
This compiles fine on both gcc and Visual Studio. The problem is, I now have to define an intermediary macro that relies on DEFINE_FUNC
, and then use that macro for defining the function instead:
#include <iostream>
#include <string>
#include <array>
#define COMMA ,
#define DEFINE_FUNC(funcName,parameters,impl) \
void funcName(parameters) impl
#define DEFINE_FUNC2(funcName,parameters,impl) \
DEFINE_FUNC(funcName,parameters,impl)
DEFINE_FUNC2(
test_func, /* function name */
float f COMMA float f2, /* Parameters */
{
std::cout<<f<<","<<f2<<std::endl;
} /* Implementation */
)
int main()
{
test_func(1.f,2.f);
}
On Visual Studio this still compiles fine, but gcc refuses to compile it because the f
and f2
parameters are now interpreted as separate arguments by DEFINE_FUNC2
because of the COMMA
:
main.cpp:15:5: error: too many arguments provided to function-like macro invocation
{
^
main.cpp:6:9: note: macro 'DEFINE_FUNC' defined here
#define DEFINE_FUNC(funcName,parameters,impl) \
^
main.cpp:12:1: error: unknown type name 'DEFINE_FUNC'
DEFINE_FUNC2(
^
main.cpp:10:5: note: expanded from macro 'DEFINE_FUNC2'
DEFINE_FUNC(funcName,parameters,impl)
^
I could just copy the contents of DEFINE_FUNC
into DEFINE_FUNC2
, but this is a very simplified example and it would cause significant redundancy in the actual code.
I tried changing float f COMMA float f2
to (float f,float f2)
to force the preprocessor to ignore the comma, but that also fails to compile:
#define COMMA ,
#define DEFINE_FUNC(funcName,parameters,impl) \
void funcName##parameters impl
#define DEFINE_FUNC2(funcName,parameters,impl) \
DEFINE_FUNC(funcName,parameters,impl)
DEFINE_FUNC2(
test_func, /* function name */
(float f , float f2), /* Parameters */
{
std::cout<<f<<","<<f2<<std::endl;
} /* Implementation */
)
Error:
main.cpp:12:1: error: pasting formed 'test_func(', an invalid preprocessing token
DEFINE_FUNC2(
^
Is there some way to make this work with both gcc and Visual Studio?
CodePudding user response:
Your last solution is mostly valid, but in a function definition, the function name and parameters do not form a single token, so you should not join them using ##
:
#define DEFINE_FUNC(funcName,parameters,impl) \
void funcName parameters impl