2013-11-02 5 views
0
#include <iostream> 

using namespace std; 

struct A 
{ 
    A() 
     : _p(new int(1)) 
    {} 

    ~A() 
    { 
     *_p = 0; 

     delete _p; 
     _p = nullptr; 
    } 

    int* _p; 
}; 

int main() 
{ 
    // 
    // Let r_to_a reference to a temporary object 
    // 
    A& r_to_a = A(); 

    // 
    // Is r_to_a still valid now? 
    // 
    cout << *r_to_a._p << endl; // Output : 1 instead of a run-time error 
} 

내가 알고 있었 듯이 임시 객체에 대한 비 const 참조는 부적절합니다. 그러나 위의 코드는 C++에서 합법적 인 것처럼 보입니다. 왜?임시 객체를 비 const로 참조하고 수명을 연장 할 수없는 이유는 무엇입니까?

제 컴파일러는 VC++ 2013

답변

2

코드는 정말하지 않습니다는 C++로 법적 것을 보여입니다. 단순히 컴파일러가 비표준 컴파일러 확장을 지원함을 보여줍니다. 임시 파일의 수명이 연장되는지 확인하려면 컴파일러 문서를 참조해야합니다. 실험 결과 확장 된 것으로 나타납니다.

그럼에도 불구하고 코드가 표준 C++에서 잘못 작성되었습니다. 당신이 /Za 옵션을 사용하여 해당 컴파일러 컴파일러 확장을 사용하지 않도록 설정하면, 그것은 또한 당신의 코드를 받아들이기를 거부한다 : 당신이 할 수있는 (외관상 파손되는) /Za를 사용하지 않도록, 또는

error C2440: 'initializing' : cannot convert from 'A' to 'A &' 

#pragma warning(error : 4239) 

또는 C/C++ -> Advanced -> Treat Specific Warnings As Errors 아래의 해당 프로젝트 설정을 변경하여이 특정 기능을 더 구체적으로 금지하십시오.

+1

확장 기능을 명시 적으로 사용 중지해도 자체 헤더를 컴파일하지 못합니다. – rubenvb

+1

@rubenvb : 확장 기능을 사용하지 않는 WindowsAPI 헤더를 컴파일하지 못할 수도 있습니다. 그러나 표준 헤더는 컴파일 가능해야합니다. (내가 틀렸다면 고쳐주세요.) – AnT

+0

@AndreyT : 그것에 대해 거대한 행을 기억하고있을 것입니다. MSVC의 라이브러리 구현 자들은 어느 시점에서'/ Za'를 공식적으로 선언하지 않았습니다. 아마도'/ Za '모드에 버그가 있었기 때문일까? 나는 이것이 표준 라이브러리를 포함하고 있다는 인상하에 있었지만, 세부 사항 (또는 어떤 헤더인지)을 기억하지 못하고 그 이후로 수정되었을 수도 있습니다. –