如何指示gcc警告我无效的函数指针转换就像g ++一样?

yus*_*suf 0 c gcc function-pointers gcc-warning

我如何指示gcc警告我有关无效的函数指针转换,比如g ++会对下面的代码做什么?

并且..为什么gcc没有警告我这个?将指针传递给do_something()时会发生什么/将会发生什么?

#include <stdio.h>

typedef void (*void_func_t) ();
typedef void (*void_int_func_t) (int, int, int);

void do_something(void_func_t f)
{
    void_int_func_t foo = f;
    foo(1,2,3);
}

void a()
{
    printf("a\n");
}

void b(int one, int two, int three)
{
    printf("%i, %i, %i\n", one, two, three);
}

int main()
{
    do_something(a);
    do_something(b);
    return 0;   
}
Run Code Online (Sandbox Code Playgroud)

输出:

?  gcc -W -Wall -Werror func.c 
?  ./a.out
a
1, 2, 3
Run Code Online (Sandbox Code Playgroud)

然而,c ++会警告/给出错误

g++ -W -Wall -Werror func.c
func.c: In function ‘void do_something(void_func_t)’:
func.c:8:27: error: invalid conversion from ‘void_func_t {aka void (*)()}’ to ‘void_int_func_t {aka void (*)(int, int, int)}’ [-fpermissive]
func.c: In function ‘int main()’:
func.c:25:19: error: invalid conversion from ‘void (*)(int, int, int)’ to ‘void_func_t {aka void (*)()}’ [-fpermissive]
func.c:6:6: error:   initializing argument 1 of ‘void do_something(void_func_t)’ [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

250*_*501 5

具有空括号的函数原型是过时的1特征.不要使用它.

如果您使用正确的声明,您将收到警告:

typedef void(*void_func_t)(void);
Run Code Online (Sandbox Code Playgroud)

由于这个旧功能,类型void(*)()void(*)(int, int, int)兼容性.前一种类型带有未指定数量的参数.这是双重问题,因为没有来自编译器的警告,并且如果使用不正确数量的参数调用函数,则行为是未定义的.

与C不同,在C++中,空括号表示函数不带参数,因此void(*)()等效于void(*)(void).


1(引用自:ISO/IEC 9899:201x 6.11.6函数声明符1)
使用带有空括号的函数声明符(不是prototype-format参数类型声明符)是一个过时的功能.