5

我编写了以下代码来测试它:

struct X
{
   char* x;
   X()
   {
      x = new char('a');
   }
   ~X()
   {
      *x = 'b';
      delete x;
   }
};

void foo(const X& x)
{
}
void goo(X& x)
{
}

int main()
{
   foo(X());
   goo(X());
}

两个函数退出后都会调用临时对象的析构函数,但我认为您只能将临时对象绑定到const引用。那为什么会goo起作用?

是 UB 和 MSVS 错了,还是没问题?

4

2 回答 2

3

这是非法的。符合标准的实现会诊断它(即它必须至少发出警告),但 MSVC++ 允许它作为扩展。

或者如果您不友善,则可能是一个错误,但是 IIRC 他们仍然允许它的原因是由于长期存在的遗留原因:名义上支持在 C++ 标准化之前为 MSVC++ 编写的代码,但是当然,一旦您允许人们编写此代码,他们就会编写它也意外地出现在新代码中,因此遗产继续存在。如果它是故意的,那么它是一个(错误)功能,而不是一个错误,对吧?无论如何,诊断格式错误的程序需要一个符合要求的实现,因此如果您没有收到警告,则编译器不符合要求。

于 2012-05-16T08:58:08.387 回答
1

这显然是一个 MS 扩展。例如,在 GCC 4.3.4 中,它无法编译,并显示以下消息:

prog.cpp: In function ‘int main()’:
prog.cpp:25: error: invalid initialization of non-const reference of type ‘X&’ from a temporary of type ‘X’
prog.cpp:18: error: in passing argument 1 of ‘void goo(X&)’
于 2012-05-16T08:58:01.763 回答