定义和使用函数指针类型,引用具有不同枚举类型参数的函数

时间:2017-07-19 22:14:28

标签: c enums function-pointers function-prototypes

我有一对接受多个参数的函数。除了一个枚举参数外,两个函数签名都是相同的类型:

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 */ }

现在因为在我的脑海中,我认为枚举是作为整数实现的,我想也许我可以输入一个与这两个签名兼容的函数,如:

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

但当然在将这些函数中的任何一个分配给该类型的变量时(例如func_t f_a = func_a),llvm-gcc会抱怨:

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]

我意识到这只是一个警告,如果我小心的话,我可能会放弃它,但我很好奇是否有一种严格/类型安全的方法在C中做这样的事情?

我希望在分配时没有警告,我希望能够将这些函数视为常见类型,而无需更改其声明的参数列表。

修改

这是我在更大的代码库中遇到的问题的一个非常小的例子。更改声明的参数列表需要对代码中其他位置的所有函数的所有直接调用进行类型转换 - 这是一个需要批次集成测试的重大更改(测试天数然后涉及其他人)(这很奇怪)嵌入式平台))在代码区域我真的不需要修改。

2 个答案:

答案 0 :(得分:0)

假设可以修改这两个函数,我会将两个函数更改为以下格式:

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

然后,当您输入两个函数中的每一个时,在引用数据时重新转换为适当的类型enum_a_p或enum_b_p。

答案 1 :(得分:0)

要通过带有描述参数的函数指针调用函数,参数必须是兼容的。指向不同类型的指针不兼容。一种解决方案是声明没有原型的函数,然后声明没有参数的函数指针(或者更准确地说是未定义的参数数量):

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, ...);

或者,您可以使用省略号:

{{1}}

但请注意,在这两种情况下都应用默认类型的促销 - 这就是为什么需要将参数af从float更改为double类型。