2017-04-20 8 views
1

는 간단한 프로그램 다음 고려 : 그것은 VC++에서 잘 컴파일하지만 g++ & clang++는 컴파일 오류를 제공C++, g ++/clang ++ vC++의 함수 주소를 출력하시오. 누가 맞습니까?

#include <iostream> 
void foo() { } 
int main() { 
    std::cout<<static_cast<void*>(foo); 
} 

.

source_file.cpp: In function ‘int main()’: 
source_file.cpp:4:38: error: invalid static_cast from type ‘void()’ to type ‘void*’ 
    std::cout<<static_cast<void*>(foo); 
           ^
:

라이브 데모 here (VC++)

참조 라이브 데모 here (clang++)

참조 라이브 데모 g++ & clang++에 의해 주어진 here (g++)

진단을 참조하십시오

그래서, 컴파일러는 C++ 표준에 따라 어떤 질문을합니까? 나는 g++ & clang++의 행동이 여기에 맞다고 생각합니다. static_cast 대신 여기 reinterpret_cast을 사용해야 함을 알고 있습니다. 이 버그는 VC++ 컴파일러에 있습니까? 대답이 C++의 특정 표준에 달려있다면 나는 그것에 대해서 알고 싶어합니다. this pointers-to-void reference에서

+0

foo가 함수 포인터로 사라집니다. – Destructor

+0

MSVC의 정확성을 원하면 MSVC14.1을 최근에 추가 된/permissive-with와 함께 사용해야합니다. 또한 일반적으로 VC++ 대신 MSVC라고도합니다. – tambre

답변

9

수행하려는 변환이 static_cast에서 수행 할 수있는 변환과 다르기 때문에 GCC와 Clang이 정확합니다. 이러한 변환은 [expr.static.cast]에 열거됩니다.기준 변환 (P2) 참조 호환 형 (P3) 다이렉트위한 피연산자를 사용

  • 변환의가 xValue에
  • 변환을 유도하는

    • 자료 : I 간단히 그 부분에서 단락 참조로 요약 할 -initialization (P4)
    • 변환 (P6) 표준 변환 시퀀스 (P7)
    • 정수/ENUM 전환 (P9, P10)의
    • 역 무효화하기
    • 유도 포인터 변환 (P11) 0
    • 베이스
    • 베이스에 유래 가리키는 포인터 부재 변환 (P12) 포인터 변환 (P13) 또한

    개체하는

  • 무효 포인터 P5 말한다 :

    다른 전환은 static_cast을 사용하여 명시 적으로 수행되지 않아야합니다.

    함수 또는 함수 포인터의 void*으로의 변환은 나열된 변환 중 아닙니다.

    특히 함수 포인터에서 void*으로의 표준 변환이 없으므로 직접 초기화가 적용되지 않습니다./2 conv.ptr]에 따르면

    유형의 prvalue T 개체 유형 인 "포인터 CVT, 에"CV 포인터 "타입의 prvalue로 전환시킬 수있다void ". 오브젝트 유형에 대한 포인터의 널 (NULL)이 아닌 포인터 값을 " cvvoid"로 변 환한 결과는 원래 포인터 값과 같은 메모리의 주소를 나타냄니다. null 포인터 값은 대상 유형의 널 포인터 값으로 변환됩니다.

    함수 포인터가 아니라 객체 포인터에 대해서만 설명합니다.

  • 1

    : 모든 종류의

    포인터 에 개체 암시 적으로 포인터로 변환 할 수 있습니다 void

    [강조 광산]

    그리고 from this function reference :

    기능 함수에 대한 포인터는 단순히 void*로 변환 할 수없는 것을 나타 내기 위해서 보이는 물체

    수 없습니다.

    +0

    이것은 컴파일러가 옳다는 질문에 대답하지 않습니다. 그래서, 표준 인용을 생각해 내면 더 좋을 것입니다 !!! – Destructor

    +0

    @Destructor 업데이트 답변 –

    관련 문제