【发布时间】:2020-09-08 01:05:04
【问题描述】:
通过void (*f)() 指针访问具有不同参数列表的函数的指针是否合法?下面的程序使用 gcc 编译时没有警告并且似乎运行正确,但它是合法的 C 语言吗?
#include <stdio.h>
#include <stdlib.h>
typedef void funp();
static void funcall( funp* F, int args, double x)
{
switch( args)
{
case 0: F(); break;
case 1: F(x); break;
}
}
static void fun0( void)
{
printf( "zero\n");
}
static void fun1( double x)
{
printf( "one\t%f\n", x);
}
int main( )
{
funcall( (funp*)fun0, 0, 17.0);
funcall( (funp*)fun1, 1, 17.0);
return EXIT_SUCCESS;
}
我用这个编译了
gcc -Wpedantic -Wall -Wextra -std=gnu11 -O2 -o ./funp funp.c
如果nargs 参数与函数所接受的参数数量不匹配,这将是未定义的行为,但如果匹配,是否合法?
【问题讨论】:
-
不是您特定问题的答案,但常见的方法是只使用一个接受
void*参数的函数指针,然后根据实际实现对其进行不同的解释。然后,此参数可以是从NULL到指向具有十几个参数的结构的指针的任何内容。如果调用者必须知道参数的数量、类型和顺序,那么整个想法在实践中就变得没那么有用了。 -
您发布的代码中的间距让我非常生气。
-
最好从
main中删除演员表。通常,此类转换可能会导致编译器抑制对不正确转换的诊断。 -
不管这种构造是否严格合法,我认为有更简洁的方法来完成同样的事情(例如,让
fun0接受一个论点并忽略它)。 -
@KonradRudolph:我最初的印象是,在看到代码块的第一秒,仅基于间距,它看起来像汇编语言(基于多个制表符停止的列,就像 asm 会用于
mnemonic op1, op2)。我就像“这是来自 HNQ,为什么我在活动的 asm 问题列表中没有看到这个?”我也不喜欢 C 的这种间距!
标签: c function pointers language-lawyer