2013-11-02 42 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選項在編譯器禁用編譯器擴展,它也將拒絕接受你的代碼:

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

另外,要避免使用/Za(這顯然打破),你可以做

#pragma warning(error : 4239) 

或更改C/C++ -> Advanced -> Treat Specific Warnings As Errors下的相應項目設置,以更有針對性的方式禁止此特定功能。

+1

當您明確禁用擴展時,它也將無法編譯它自己的頭文件;-) – rubenvb

+1

@rubenvb:我的印象是它可能無法編譯WindowsAPI頭文件的擴展禁用。但是標準頭文件應該是可編譯的。 (糾正我,如果我錯了。) – AnT

+0

@AndreyT:我確信我記得一些巨大的行:有些時候MSVC的圖書館實施者正式宣佈他們不支持'/ Za'。也許是因爲'/ Za'模式存在錯誤?我的印象是這包括標準庫,但我不記得細節(甚至是什麼標題),並且從那以後它可能已經被修復了。 –

相關問題