这些章节表明,使用不兼容的类型调用函数指针将导致未定义的行为。
C89 3.5.4.3 p9
两个函数类型要兼容,都必须指定兼容的返回类型。此外,如果两个参数类型列表都存在,则在参数数量和省略号终止符的使用方面应保持一致;相应参数的类型应兼容。
C89 3.5.4.1 p2
要使两个指针类型兼容,它们都必须具有相同的限定符,并且都必须是指向兼容类型的指针。
C89 3.3.4 p3
一个指向某种类型的函数的指针可以转换为指向另一种类型的函数的指针,反之亦然;结果应与原始指针相等。如果使用转换后的指针调用具有不兼容类型的被调用函数,则行为未定义。
将其他对象指针类型强制转换为void指针是否兼容?
C89 3.3.4 p3
然而,保证给定对齐方式的对象的指针可以被转换为具有相同或较少严格对齐要求的对象的指针,然后再转换回来;结果应与原始指针相等(具有字符类型的对象具有最不严格的对齐方式)。
C89 3.1.2.5 p20
指向void的指针应具有与字符类型的指针相同的表示和对齐要求。
C89 3.2.2.3 p1
可以将指向void的指针转换为任何不完整或对象类型的指针,反之亦然;结果应与原始指针相等。
C89 3.5.4.3 p9
两个函数类型要兼容,都必须指定兼容的返回类型。此外,如果两个参数类型列表都存在,则在参数数量和省略号终止符的使用方面应保持一致;相应参数的类型应兼容。
C89 3.5.4.1 p2
要使两个指针类型兼容,它们都必须具有相同的限定符,并且都必须是指向兼容类型的指针。
C89 3.3.4 p3
一个指向某种类型的函数的指针可以转换为指向另一种类型的函数的指针,反之亦然;结果应与原始指针相等。如果使用转换后的指针调用具有不兼容类型的被调用函数,则行为未定义。
将其他对象指针类型强制转换为void指针是否兼容?
C89 3.3.4 p3
然而,保证给定对齐方式的对象的指针可以被转换为具有相同或较少严格对齐要求的对象的指针,然后再转换回来;结果应与原始指针相等(具有字符类型的对象具有最不严格的对齐方式)。
C89 3.1.2.5 p20
指向void的指针应具有与字符类型的指针相同的表示和对齐要求。
C89 3.2.2.3 p1
可以将指向void的指针转换为任何不完整或对象类型的指针,反之亦然;结果应与原始指针相等。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *foo(void) {
int *data = malloc(sizeof(int));
*data = 42;
return data;
}
int main(int argc, char *argv[]) {
void *(*fn_ptr)(void) = foo;
void *raw = fn_ptr();
int data = *(int *)raw;
printf("%d\n", data);
}
int *(*fn_ptr)(void) = foo;
的翻译是什么? - David C. Rankin