2017-10-30 15 views
20

다음 코드를 대하는 옵션 -std=c++1y와 g ++ 버전 5.4.0로 컴파일 할 수 없습니다기본 인수 함수 역 참조 - C++ (14) C++ 11

void f(int=0) ; 

int main() { 
    f(); // ok 
    (*f)(2);// ok 
    (*f)();// ok c++11; error with c++14: too few arguments to function 
    return 0; 
} 

기능 기본 인수를 선언 , 그래서 여기서 무엇이 잘못 되었습니까? 도움을 주신 덕분에 .

g++ -c -std=c++11이 컴파일됩니까?

+1

확실한 대답은 새로운'g ++'버전을 시도하는 것입니다. 5 줄은 낡았 고, 5.4는 최신 마이너 버전조차도 아니다. 이와 같은 경우에는 GCC Bugzilla를 검색하는 것이 현명합니다. 문제는 이미 알려져 있기 때문에 이전 버전으로 필터링하는 데 시간이 걸리고 때로는 발생하지 않을 수 있습니다. –

+0

컴파일러 버그와 같습니다. Clang은 C++ 11 및 C++ 14 모두에서이 코드를 거부합니다. – StoryTeller

+0

이것은 최적화 단계의 순서와 관련이있을 수 있습니까? 인수가 처리되기 전에 직접 호출에 최적화 된 함수 포인터 –

답변

8

기본 인수는 함수 형식의 일부가 아니므로 함수 포인터를 암시 적으로 함수 포인터로 변환 한 다음 해당 포인터를 간접적으로 변환하면 삭제됩니다.

+3

그러면 g ++ -c -std = C++ 11이 왜 컴파일됩니까? –

+0

잘 모르겠다. 컴파일해서는 안된다. –

+1

이것은 잘 컴파일합니다 : https://ideone.com/InD4T7 –

25

(*f)()을 유효한 것으로 받아들이는 것은 GCC 버그입니다. 표준 문자는 함수 이름을 단항 문자 *과 함께 사용하면 함수 이름이 포인터로 감소해야 함을 나타냅니다. 그런 다음 포인터를 역 참조하여 호출 식의 함수 주소를 얻습니다.

하지만 GCC는 똑똑해 보이고 위의 동작은 생략합니다. 그것은 (*f)을 단순히 f으로 취급합니다. f을 호출하는 것은 기본 인수를 사용하여 수행 할 수 있습니다.

그러나 GCC가 부식을 수행하도록 강제 할 수 있습니다. 함수 이름에 단항 +을 적용하면 포인터가 강제로 소멸됩니다. 그래서 두 가지를 다음

(+f)(); 
(*+f)(); 

원인 GCC는 GCC 7.2GCC 6.3 모두에서 하나의 표준 개정에 error: too few arguments to function을 방출 할 수 있습니다.

+0

@StoryTeller 위 Clang은 C++ 11 및 C++ 14에서 OP 코드를 거부했습니다. Clang도 같은 버그가 있습니까? – KeithSmith

+6

@KeithSmith - ** 나는 ** StoryTeller입니다. 그리고 Clang은 원래 코드를 거부합니다. 여기에 버그가 없다. – StoryTeller

+0

Visual Studio 2017은 원래 코드를 기꺼이 받아들입니다. (+ f)() 및 (* + f)() 및 (+ * f)() - 모두 내부 컴파일러 오류가 발생합니다. –