2013-11-02 40 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'模式存在错误?我的印象是这包括标准库,但我不记得细节(甚至是什么标题),并且从那以后它可能已经被修复了。 –

相关问题