英文:
Casting function pointers with arguments of different pointer types
问题
(1) 是不是保证直接使用 pf(&a);
会正常工作?或者需要像 (2) 一样将其转换回去?
英文:
#include <stdio.h>
typedef struct {
int i;
} A;
void f(A* a) {
printf("%d\n", a->i);
}
int main() {
void (*pf)(void*) = (void(*)(void*))&f;
A a;
pf(&a); // 1
((void(*)(A*))pf)(&a); // 2
}
A function pointer void(*)(A*)
is cast to a function pointer void(*)(void*)
. Then it is called with an argument of type A*
.
Is it guaranteed to work correctly when used directly (1)? Or it is needed to cast it back like (2)?
答案1
得分: 13
以下是您要的翻译内容:
First of all. The casts between pointer to functions with different signatures are allowed by C11 standard, 6.3.2.3p8
首先,根据C11标准,6.3.2.3p8,允许不同签名的函数指针之间的强制转换:
一个类型的函数指针可以被转换为另一个类型的函数指针,然后再转回去;结果必须与原指针相等。
Method 1
pf(&a);
// 1
No. This is undefined behavior and it is not guaranteed to work. From C11 standard, 6.3.2.3p8:
不行。这是未定义行为,不能保证其正常工作。根据C11标准,6.3.2.3p8:
...如果使用转换后的指针来调用与引用类型不兼容的函数,行为是未定义的。
Method 2
((void(*)(A*))pf)(&a);
// 2
It is fine and defined. because the function with signature void(A*)
is called via a pointer to void(A*)
.
这是可行且被定义的,因为具有
void(A*)
签名的函数是通过指向void(A*)
的指针进行调用的。
EDIT
The compatibility of function types is defined in 6.7.6.3p15:
函数类型的兼容性在6.7.6.3p15中有定义:
为了使两个函数类型兼容,它们都必须指定兼容的返回类型。此外,如果两者都存在,参数类型列表必须在参数数量和省略号终结符的使用方面一致;相应的参数必须具有兼容的类型。
函数void(void*)
和void(A*)
不兼容,因为类型void*
和A*
不兼容。
英文:
First of all. The casts between pointer to functions with different signatures are allowed by C11 standard, 6.3.2.3p8
> A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer.
Method 1
> pf(&a);
// 1
No. This is undefined behavior and it is not guaranteed to work. From C11 standard, 6.3.2.3p8:
> ... If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.
Method 2
> ((void(*)(A*))pf)(&a);
// 2
It is fine and defined. because the function with signature void(A*)
is called via a pointer to void(A*)
.
EDIT
The compatibility of function types is defined in 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. ...
The functions void(void*)
and void(A*)
are not compatible because types void*
and A*
are not compatible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论