接受任意参数的函数指针能否兼容参数不同的函数?
关于C语言函数签名与函数指针调用的疑问
已知的基础概念
- 在C语言中,函数声明
TYPE func(void);表示该函数接受无参数;而TYPE func();表示函数接受任意参数,这是C与C++的关键区别之一。 - 参数签名不同的函数,对应的函数指针彼此不兼容。
- 函数指针可以转换为其他类型,再转换回原类型后调用是合法的(即“往返转换”操作可行)。
核心疑问
我想明确:通过参数签名不匹配的函数指针调用函数时,实际会发生什么?我清楚这大概率属于未定义行为(undefined behavior),但对TYPE func();这种“接受任意参数”的定义存在疑惑,可能我的理解本身有误。
示例代码说明
以下代码用于展示我的思路:
#include <stdio.h> #include <stdbool.h> void (*func)(); /* 声明为接受任意参数的函数指针 */ void func_1(int x); /* 带1个参数的函数 */ void func_2(int x, float y); /* 带2个参数的函数 */ enum MODE {PRINT_THEM, NOTE_THEM} mode; int main(void) { printf("Printing...\n"); mode = PRINT_THEM; func_1(8); func_2(9, 10.0F); printf("Noting...\n"); mode = NOTE_THEM; func = func_1; func(); /* 按“接受任意参数”的理解,这里不传参数,但函数本身需要1个参数,不过此时不会使用参数 */ func = func_2; func(); /* 同理,不传参数,函数本身需要2个参数,但此时不会使用参数 */ return 0; } void func_1(int x) { if (mode == NOTE_THEM) printf("func_1() has 1 argument: (int)\n"); else /* mode == PRINT_THEM */ printf("x == %d\n", x); } void func_2(int x, float y) { if (mode == NOTE_THEM) printf("func_2() has 2 arguments: (int, float)\n"); else /* mode == PRINT_THEM */ printf("x == %d, y == %f\n", x, y); }
核心思路
- 当
mode == PRINT_THEM时,函数需要使用传入的参数值,此时无法使用通用函数指针调用; - 当
mode == NOTE_THEM时,函数完全不会使用参数值(哪怕是垃圾值也不影响),此时希望能用“接受任意参数”的函数指针(这里用无参数形式)来调用,避免被迫编写占位参数。
比如我不想写这种冗余的占位代码:
mode = NOTE_THEM; func_1(placeholder_int); func_2(placeholder_int, placeholder_float);
想到的替代方案
不使用函数指针,而是借助C99的复合字面量(compound literals),依赖默认初始化来满足编译器的参数要求,无需关注参数的具体值:
mode = PRINT_THEM; func_1( (FUNC_1_ARGS){8} ); func_2( (FUNC_2_ARGS){9, 10.0F} ); mode = NOTE_THEM; func_1( (FUNC_1_ARGS){} ); func_2( (FUNC_2_ARGS){} );
内容的提问来源于stack exchange,提问作者Rich Jahn
相关产品推荐
相关产品推荐

