一つのテーマから思いついたC++コンパイラの最適化問題
4223 ワード
この2,3日1つの問題を見て、見たところ簡単で、しかし使う知識は本当に少なくなくて、原題は以下の通りです:
最初に考えたのは、コンパイラの最適化です.
コンパイラは最適化されたと推測される:const Base&b=Base();このように書くと、意味によっては:
1.Baseのコンストラクタを呼び出す
2.Baseの付与関数b=一時オブジェクトを呼び出すが、コンパイラはこのような2つのステップを踏む必要はないと考え、Baseのコンストラクション関数を直接呼び出す...
その後、大侠Aの指導を経て、問題点を指摘した.
Base b=aの場合、bはまだ構造されていないので、まずbを構造し、次に値を付ける必要があります.c++コンパイラの設計者は、最適化しないことができますか?だからすべてのc++でこの行為を規定して、すなわちBase b=aはBase b(a)で、これもc++文法のsweetです.
うん....ではしばらくconst Base&b=Base();コンパイラによってBaseb(Base()になってしまうと、やはりデフォルトのコンストラクタとコピーコンストラクタが呼び出されるでしょう.プログラムが間違っていないのに!!!
キーパーソンBが現れた:
こんなに英語が山積みになっているのを見てまたぼんやり...心を静めてよく読みました.
肝心なのはこの話にある.
明らかに私がテストしたVC、GCCはすべて第1の方法を選んで直接引用を右の値にバインドします...~
参照に関するいくつかの説明は、ネットワークから抜粋しています.http://blog.csdn.net/wfwd/article/details/763551
#include "stdafx.h"
class Base
{
public:
Base(){}
virtual ~Base(){}
Base(const Base &other); // ,
private:
Base &operator=(const Base &other);
} ;
int _tmain(int argc, _TCHAR* argv[])
{
const Base &b = Base() ; // ? , !
return 0;
}
最初に考えたのは、コンパイラの最適化です.
コンパイラは最適化されたと推測される:const Base&b=Base();このように書くと、意味によっては:
1.Baseのコンストラクタを呼び出す
2.Baseの付与関数b=一時オブジェクトを呼び出すが、コンパイラはこのような2つのステップを踏む必要はないと考え、Baseのコンストラクション関数を直接呼び出す...
その後、大侠Aの指導を経て、問題点を指摘した.
Base b=aの場合、bはまだ構造されていないので、まずbを構造し、次に値を付ける必要があります.c++コンパイラの設計者は、最適化しないことができますか?だからすべてのc++でこの行為を規定して、すなわちBase b=aはBase b(a)で、これもc++文法のsweetです.
うん....ではしばらくconst Base&b=Base();コンパイラによってBaseb(Base()になってしまうと、やはりデフォルトのコンストラクタとコピーコンストラクタが呼び出されるでしょう.プログラムが間違っていないのに!!!
キーパーソンBが現れた:
,const Base &b = Base() ; , , 。
ISO/IEC 14882:2003(E)
8.5.3 References
4 5
— Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const).
[Example:
double& rd2 = 2.0; // error: not an lvalue and reference not const
int i = 2;
double& rd3 = i; // error: type mismatch and reference not const
—end example]
— If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined):
— The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
— A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.93)
こんなに英語が山積みになっているのを見てまたぼんやり...心を静めてよく読みました.
肝心なのはこの話にある.
— If the initializer expression is an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with “cv2 T2,” the reference is bound in one of the following ways (the choice is implementation-defined):// , , , ( ):
— The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.//
— A temporary of type “cv1 T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.// , , 。
明らかに私がテストしたVC、GCCはすべて第1の方法を選んで直接引用を右の値にバインドします...~
参照に関するいくつかの説明は、ネットワークから抜粋しています.http://blog.csdn.net/wfwd/article/details/763551
/*
(1)& , 。
(2) 。
(3) , 。
(4) , , , 。
ra=1; a=1;
(5) , , ,
, , 。
: , 。&ra &a 。
(6) 。 , 。
*/
, :
(1) 。 Effective C++[1] Item 31。 , " " , 。
(2) new 。 Effective C++[1] Item 31。 , ( new ), 。 , , , ( new ) , memory leak。
(3) , const。 Effective C++[1] Item 30。 (business rule) , , 。 ( ), 。
(4) :
<< >>, , :cout << "hello" << endl; 。 : 。 , ( ) , , << ! 。 << 。 , 。 , , C++ 。 =。 , , :x = j = 10; (x=10)=100; , 。 。