2017-03-29 21 views
0

g ++에서 다음 코드 부분에 대해 잘못된 포인터 전환에 대해 경고하도록 어떻게 지시 할 수 있습니까?g ++에서 잘못된 함수 포인터 변환에 대해 경고하도록 gcc에 지시하는 방법은 무엇입니까?

그리고 왜 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; 
} 

출력 :

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

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] 
+0

'-Weverything'을 사용할 수있는 곳에서'gcc' 대신'clang'을 사용할 수 있습니까? –

+1

C 및 C++은 다른 언어입니다. obsoletcence를 사용하면서도 유효한 C 기능을 사용한다면 호환 컴파일러가 왜 경고해야합니까? – Olaf

+0

아니요, @ FiddlingBits 내 경우에는 불가능합니다. @Olaf, C에서'void foo()'또는'void foo (void)'와 같은 함수를 삭제하는 것과는 상당한 차이가 있음이 분명하지 않았습니다. 그래서 궁금 해서요. 왜 나는이 질문을했다. – yussuf

답변

5

빈 괄호가있는 함수 프로토 타입은 시대에 뒤 떨어진 1 기능입니다. 사용하지 마십시오. 올바른 선언을 사용하는 경우

, 당신은 경고를 얻을 것이다 :

typedef void(*void_func_t)(void); 

이 때문에 기존 기능에, 유형 void(*)()void(*)(int, int, int)가 호환됩니다. 전자 형식은 불특정 다수의 인수를 취합니다. 이것은 컴파일러로부터 경고가 없기 때문에 문제가 많으며 잘못된 인수를 사용하여 함수를 호출하면 동작이 정의되지 않습니다.

C와 달리 빈 괄호는 함수가 인수를 취하지 않음을 의미하므로 void(*)()void(*)(void)과 같습니다.


1 을 (: ISO/IEC 9899 :에서 인용 201x 6.11.6 함수 을 선언시 1)
함수의 사용이 빈 괄호 선언시 (되지 프로토 타입 포맷 파라미터 형 선언자)는이며 노후화 된 기능.

+0

참조 주셔서 감사합니다, 그것은 물론, 무엇을 찾아야 할지를 아는 데 도움이됩니다 ... Wstrict-prototypes가 그 냄새를 발견하는 데 도움이 될 것 같지만 내 코드베이스에서 1000 가지 경고를 이끌 것입니다. – yussuf