Home > Blockchain >  How to declare an array of function pointers for functions with different arguments?
How to declare an array of function pointers for functions with different arguments?

Time:04-21

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.

  • Related