2012年(158)
分类: C/C++
2012-11-20 10:21:18
先看一段代码:
#include
using namespace std;
class foo{
public:
foo() { cout<<"default constructor
calling."<
foo bar()
{
foo t;
return t;
}
int main(void)
{
{
foo a = bar();
// gcc3.4.2中
// default
constructor calling.
// destructor calling.
//
VC2005(77626-009-0000007-41837)中
// default constructor
calling.
// copy constructor calling.
// destructor
calling.
// destructor calling.
}
cout <<
"--------" << endl;
{
foo b;
b =
bar();
// gcc3.4.2中
// default constructor
calling.
// default constructor calling.
// assigned
operator calling.
// destructor calling.
// destructor
calling.
// VC2005(77626-009-0000007-41837)中
// default
constructor calling.
// default constructor calling.
// copy constructor calling.
// destructor calling.
// assigned operator calling.
// destructor calling.
// destructor calling.
}
return 0;
}
问题就在
foo bar()
{
foo t;
return
t;
}
中,return t 时调不调用拷贝构造函数? 更一般的说,在最近的C++标准中,具名对象(且这个对象有side
effects用途时)返回时应不应该优化?
争论太多了,留在这里“秋后问斩”^_^
网友评论2012-11-20 10:22:26
ork
不可否认这个编译器特性是值得关心的,但我认为它是无害的。就此例的类型看,出现“无意间由于优化产生了非预期的结果”的可能性几乎为0
a、在普通使用(不确切的说,就是对此无知的情况下),一般不会出现这么简单的结构(这么简单的结构对有目的的使用来说是无意义的),且容易看出,在foo bar()中的foo t;return t;之间加入一些对t的操作,便会减少一些优化差异
b、一个设计正确的类,构造器、赋值操作附、析沟器等应该保证对象内部状态的平衡(如果不能保证,那么即使编译器没问题,最终的二进制产品也是异常的),既如此,此例中编译器的体现的优化差异最多也就会带来性能的差异而非结果的
c、在意识到此差异的情况下且须特意构造产生的差异的条件,那么明确差异利用差异就成了使用者的责任了
d、由此很自然的能想到“会不会还有其他未知的差异呢”,这也在情理之中,也只能再看了,呵呵
没有研读std关于此方面的规定,冒昧发言,还
网友评论2012-11-20 10:22:16
周星星
您有两个观点:
a. 程序员不应该操心编译器怎么优化
b. 这个优化或不优化都不会引起行为的不正确
我以同一个事例来反驳您的观点:
假设我用一个自动测试工具来测试本文中的代码,比如
if( 其输出 == 某某某 ) 输出“结果正确”
else 输出“结果错误”
如果你不考虑“编译器怎么优化”,那么结果只有可能是一个正确,要么是debug正确,要么是release正确,因为Debug版本Release版本的输出不一样,就否定了你自己的 b 观点。
如果你要使结果正确,那就要写成
if( 其输出 == ( 是否优化 ? 某某某1 : 某某某2 ) ) 输出“结果正确”
else 输出“结果错误”
那么从测试代码中就可以看出你已经考虑优化和不优化两种情况了,这又否定了你自己的 a 观点。
网友评论2012-11-20 10:22:07
周星星
1。返回值优化只是在release下才有效
--- 首先C++可没有规定什么Debug版本Release版本;其次,如果C++标准规定了在这种情况下必须优化,那么即使在Debug下它也必须优化,如果C++标准禁止了在这种情况下的优化,那么即使在Release下它也不可以优化,如果如果C++标准没有任何规定,那么优不优化是编译器的事,但它也必须保证输出结果的一致性,但现在Debug下和Release下并不一致。
2。我们应该操心编译器怎么优化我们的程序么
--- 这个问题回答起来太复杂,有时候不得不关心,而大部分时候并不需要关心它,所以我无法回答true or false。不过庆幸的是这个问题和这篇文章无关,这篇文章关心的是C++标准是怎么规定这个NRV的,在弄清楚这个问题后就可以知道谁违反了C++标准。
3。会出现行为不正确的情况么?
--- 哇,输出差异成这样,那……
网友评论2012-11-20 10:21:57
小明
你所说的是VS2005下的DEBUG版本吧
RELEASE版本的输出是这样的
default constructor calling.
destructor calling.
--------
default constructor calling.
default constructor calling.
assigned operator calling.
destructor calling.
destructor calling.
我想返回值优化只是在release下才有效。
我们应该操心编译器怎么优化我们的程序么
会出现行为不正确的情况么?