Reputation: 1137
I try to use code which is generating functions via a macro, which looks like this:
File A (Provided file I can't change anything here):
#define FUNCTION_GENERATOR(NUM) \
void MyGeneratedFunctionNo##NUM##(void) \
{ \
another_function_call(NUM); \
} \
FUNCTION_GENERATOR(1)
FUNCTION_GENERATOR(2)
FUNCTION_GENERATOR(3)
File B (My file where I wanna use function pointers to the generated functions from File A):
typedef void (*function_ptr) (void);
function_ptr func_array[3];
func_array[0] = MyGeneratedFunctionNo1;
func_array[1] = MyGeneratedFunctionNo2;
func_array[2] = MyGeneratedFunctionNo3;
...
Naturally the compiler complains that MyGeneratedFunctionNo1, MyGeneratedFunctionNo2, MyGeneratedFunctionNo3 are not defined.
Is there any way to use function pointers with this generated functions?
Upvotes: 1
Views: 247
Reputation: 320551
The problem has nothing to do with function pointers per se. You will not be able to access these functions from other translation units in any way, pointers or not, because they are not declared in other translation units.
The typical macro based technique implies providing and using two macros: one for generating declarations and one for generating definitions
#define FUNCTION_GENERATOR_DECL(NUM) \
void MyGeneratedFunctionNo##NUM(void);
#define FUNCTION_GENERATOR_DEF(NUM) \
void MyGeneratedFunctionNo##NUM(void) \
{ \
another_function_call(NUM); \
}
After that you use the "definition" macro instantiations in some implementation file (as you already do)
FUNCTION_GENERATOR_DEF(1)
FUNCTION_GENERATOR_DEF(2)
FUNCTION_GENERATOR_DEF(3)
and you typically place the "declarator" macro instantiations into some header file.
FUNCTION_GENERATOR_DECL(1)
FUNCTION_GENERATOR_DECL(2)
FUNCTION_GENERATOR_DECL(3)
P.S. Also, note an important subtle point mentioned by @James Kanze in the comments (and which I missed initailly). The ##
operator shall not be used to form invalid preprocessing tokens. In the preprocessor grammar (
is a separate independent preprocessing token (punctuator), while the function name is also a separate independent preprocessing token (identifier). If you attempt to forcefully concatenate the function name to the (
by using the ##
operator, you'll end up with an invalid preprocessing token and undefined behavior.
Don't concatenate the (
to the function name. Remove the second ##
from your macro definition. It will work as intended without it.
Upvotes: 2
Reputation: 26114
Just like any other function, you have to declare them. This is typically done in a header file.
You can do this directly, or you can define a macro similar to the one you have that defines the function.
Concretely, place this in a header file, which you include in both the file you define your functions in and in the file you use them:
extern void MyGeneratedFunctionNo1(void);
Upvotes: 2