以下代碼的行爲是否定義良好?在構造之前綁定對象的引用
struct X { int i; }; // trivial
struct Y : X { Y(){} }; // non-trivial
extern X xobj;
int& r1 = xobj.i; // #1
X xobj;
extern Y yobj;
Y& r2 = yobj; // #2
// int& r3 = yobj.i; // #3 - this is UB according to the standard
Y yobj;
此代碼的靈感來自於C++標準中的示例,即草案N4140 [class.cdtor]/1。
這就是那款曰:
對於一個不平凡的構造方法的對象,指的是任何非靜態成員或基類的構造函數之前的對象 的開始未定義行爲的執行結果。對於具有非平凡的析構函數的對象,在析構函數完成後引用該對象的任何非靜態成員或基類 執行會導致未定義的行爲。
下面的例子顯示瞭如何指針可以和不可以綁定到對象。
那麼直觀看來,#1
和#2
是明確的,如果沒有註釋而#3
調用UB,但是,第一,實例並不規範,第二,有沒有在這個例子中引用的提及,第三和最重要的,上述段落並不意味着否則行爲是明確的。還是呢?或者也許我錯過了另一個相關的標準報價?
編輯:答案可能(可以說)是肯定的,如果對象具有靜態存儲時間,但它們也可以局部,如:
struct A { A(){} };
struct B { B(A&){} };
struct C {
B b;
A a;
C() : b(a) {}
};
int main() {
C c;
}
其實,這是最初的靈感爲這個問題,看到Circular dependency in constructor initialization list
「引用任何非靜態成員導致未定義的行爲」 - 引用正是引用所做的(因此名稱)。 – molbdnilo
@molbdnilo我明白,但它不能解釋會發生什麼*否則*(例如,在構造函數開始之前爲類的構造函數開頭),這就是問題的關鍵。 –
「指它」意味着提及它(這是英文單詞「refer」)。 –