Define and use the function pointer type, referring to functions with parameters of different enumeration types

I have a couple of functions that take multiple parameters. Both function signatures are of the same type, except for one parameter enum:

typedef enum { a_1, a_2, a_3 } enum_a_t;
typedef enum_a_t * enum_a_p;

typedef enum { b_1, b_2      } enum_b_t;
typedef enum_b_t * enum_b_p;

void func_a(int ai, float af, enum_a_p ae_ptr) { /* blah */ }
void func_b(int ai, float af, enum_b_p ae_ptr) { /* blah */ }

      

Now, since in my head I think that enums are done as integers, I thought that maybe I could typedef a function that is compatible with both of these signatures, something like:

typedef void (* func_t)(int, float, int *);

      

But of course, when assigning any of these functions to a variable of this type (for example func_t f_a = func_a

), llvm-gcc complains:

warning: incompatible pointer types initializing 'func_t' (aka 'void (*)(int, float, int *)') with an expression of type 'void (int, float, enum_a_p)' (aka 'void (int, float, enum_a_t *)') [-Wincompatible-pointer-types]

      

I understand this is just a warning, and I can probably get away with it if I'm careful, but I was curious if there is a strict / type safe to do something like this in C?

I wish I had no warning about the assignment, and I would like to be able to treat these functions as a generic type without changing their declared parameter lists.

change

This is a very small example of a problem I encountered in a much larger codebase. Changing the declared parameter lists would require typecasting all direct calls to those functions elsewhere in the code - a significant change that would require a lot of testing of the integration (testing days and then involving others (this on a weird embedded platform)) in areas of code that I really don't needs to be changed.

+3


source to share


2 answers


Assuming the two functions could be changed, I would change the two functions to format:

void func_a(int ai, float af, void * ae_ptr) { /* blah */ }
void func_b(int ai, float af, void * ae_ptr) { /* blah */ }

      



Then, when you enter each of the two functions, go to the appropriate type enum_a_p or enum_b_p when referencing the data.

0


source


To call a function using a function pointer with the described arguments, the arguments must be compatible. Pointers to different types are not compatible. One solution is to declare functions without a prototype, and then declare a function pointer with no arguments (more precisely, with undefined number of arguments):

void func_a();
void func_b();

void func_a(int ai, double af, enum_a_p ae_ptr) { /* blah */ }
void func_b(int ai, double af, enum_b_p ae_ptr) { /* blah */ }

typedef void (* func_t)();

      

Alternatively, you can use ellipsis:



void func_a(int ai, double af, ...) { /* blah with varargs */ }
void func_b(int ai, double af, ...) { /* blah with varargs */ }

typedef void (* func_t)(int ai, double af, ...);

      

Note, however, that in both cases the default type rules apply - so the af argument must be changed from float to double type.

0


source







All Articles