gpt4 book ai didi

c - 将void(*)()指针用于其他功能

转载 作者:行者123 更新时间:2023-12-03 07:28:22 24 4
gpt4 key购买 nike

通过void (*f)()指针访问具有不同参数列表的函数的指针合法吗?下面的程序使用gcc进行编译时没有警告,并且似乎可以正常运行,但是它合法吗?

#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参数与函数采用的参数数量不匹配,那将是不确定的行为,但是如果存在匹配项,是否合法?

最佳答案

在这种情况下,通话是合法的。

C standard的6.7.6.3p15节阐明了使两个函数类型兼容的原因(相关部分以粗体显示):

For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)



因此,您有一个类型为 typedef的代码:
void()

和具有类型的函数:
void(void)
void(double)

这两个函数定义不使用省略号( ...),因此可以满足第一个条件。对于第二个条件,让我们看一下 默认参数提升是什么。这些在6.5.2.2p6节中指定:

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.



第一个函数没有参数,因此是兼容的。第二个函数有一个 double参数,它与默认参数Promotions匹配,因此也是兼容的。

为了提供更多示例,以下功能也将兼容:
void f1(long);
void f2(int);

但是这些不会:
void f3(float);
void f4(char);
void f5(short);

关于c - 将void(*)()指针用于其他功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61933862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com