I am writing some tests for my project, and the functions have the same return type but a different number of parameters. I want to use an array of function pointers to call these test functions. How to declare an array of function pointers for such functions?
The functions are declared as:
bool test1();
bool test2(char const *string, uint32_t length);
CodePudding user response:
Consider that function pointers are not magic tricks, they still have to abide to the ABI calling convention, meaning that a function with a certain signature is intrinsically different from a function with a different signature.
Using a function pointer is more of a way to have dynamic methods, than to achieve polymorphism. EDIT: This is not polymorphism.
However, you can accomplish somewhat you ask by replacing each of the test functions to accept a void*
and then code your parameters in a struct.
// Declare the test functions
//bool test1();
bool test1(void* struct_address)
{
// struct address unused.
}
// Parameters for test2
struct test2{
char const* string;
uint32_t* length;
}
//bool test2(char const *string, uint32_t length);
bool test2(void* struct_address)
{
struct test2 test2_s = *(struct test2*)(struct_address);
// Work with test2_s
}
// Declare the function pointer
bool (*test_ptr)(void *);
// call test1
test_ptr = test1; test_ptr((void*)NULL);
// call test2
struct test2 test2_s = {param1,param2};
test_ptr = test2; test_ptr((void*)&test2_s);
Be careful because if you pass the wrong struct type you will get memory leaks and segmentation errors. Since this is a test environment, however, this can be mitigated.
CodePudding user response:
In C, an empty parameter list in a function declaration does not mean that the function takes no argument; rather, it means that it takes an unspecified number of arguments.1
So, syntactically at least, you can specify an array of function pointers, each with an unspecified number of arguments (but a fixed return type), like this: bool (*FnPtrArray[100])();
. You can then assign, to different elements of such an array, addresses of functions with different argument types and numbers. However, there can then be no compile-time check that those functions are called correctly, or any implicit conversion of given argument types to the 'correct' forms.
The code below illustrates this (but note that I do not recommend using code like this, because of the inherent dangers that passing incorrect arguments can cause):
#include <stdio.h>
#include <stdbool.h>
bool Foo(int a) {
printf("Foo: %d ...\n", a);
return a % 2;
}
bool Bar(double x, double y) {
printf("Bar: %5.3lf %5.3lf...\n", x, y);
return x < y;
}
int main()
{
bool (*FnPtrArray[100])();
// So we can't tell at compile time which elements point where ...
printf("Enter a number: ");
int n = 42;
scanf("%d", &n);
if (n % 2) {
FnPtrArray[0] = Foo;
FnPtrArray[1] = Bar;
}
else {
FnPtrArray[1] = Foo;
FnPtrArray[0] = Bar;
}
// Notes assuming given "n" is odd ...
printf("%d\n\n", FnPtrArray[0](3)); // Works
printf("%d\n\n", FnPtrArray[0](3.0)); // Wrong argument type
printf("%d\n\n", FnPtrArray[1](1.0, 2.0)); // Works
printf("%d\n\n", FnPtrArray[1](1, 2)); // Wrong argument types
printf("%d\n\n", FnPtrArray[1](1.0)); // Wrong number of args
return 0;
}
Here's a link to the above code on Compiler Explorer, for those who want to test with various compilers and settings.
1 This is very different from C , where an empty formal parameter list does mean no argument.