简体   繁体   中英

How to instruct gcc to warn me about invalid function pointer conversion just as g++ would do?

How can i instruct gcc to warn me about invalid function pointer conversions like g++ would do for the following piece of code?

And.. why doesn't gcc warn me about that? What could / will happen when passing a pointer to a to 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;   
}

output:

➜  gcc -W -Wall -Werror func.c 
➜  ./a.out
a
1, 2, 3

c++, however would warn / give errors

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]

A function prototype with empty parenthesis is an obsolescent 1 feature. Don't use it.

If you use the correct declaration, you will get warnings:

typedef void(*void_func_t)(void);

Due to this old feature, the types void(*)() and void(*)(int, int, int) are compatible. The former type takes an unspecified number of arguments. This is doubly problematic, because there is no warning from the compiler, and if you call the function with incorrect number of arguments, the behavior is undefined.

Unlike in C, in C++ empty parenthesis mean that the function takes no arguments, thus void(*)() is equivalent to void(*)(void) .


1 (Quoted from: ISO/IEC 9899:201x 6.11.6 Function declarators 1)
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM