2017-03-01 64 views
5

這基本上是有關DR 712的my prior question的延續。讓我先解釋一下爲什麼我堅持要看一些可能被認爲是舊的東西,如C++ 11標準,但我的問題是[C++ 11]中的[basic.def.odr]這部分已經很難理解了,在我深入研究當前草案中的同一部分之前,我想完整地介紹這一部分,在我看來,更加複雜。繼續「我只是不明白DR 712」

對我之前問題Austing Hasting的回答很好,但我仍然有一點在C++ 11的[basic.def.odr]/2中不明確。考慮這一點,非常簡單的例子:

const int i = 1; 
int main() 
{ 
    int j = i; 
} 

從[basic.def.odr]/2在C++ 11 iodr-usedint j = i;作爲i是滿足對於出現在要求的對象一個常數表達式和左值到右值的轉換立即應用於i。這對我來說沒有多大意義,因爲i明確地用於聲明int j = i;,正如可以在稍微修改的代碼here中看到的那樣,其中我強制變量i不在編譯代碼之外進行優化。

當然,我上面的推理肯定有錯,因爲我不相信C++ 11在這樣一個簡單的例子中可能是錯的。再次,我現在想念什麼?

+4

您的示例代碼中所需的全部內容都是***「i」的值***。這意味着它可以被優化,並且不需要分配存儲空間。 –

回答

9

我想把我對標準「used」和「one definition rule used」的理解轉化爲更直觀的東西。除「使用」和「使用ODR」之外的術語不打算作爲下面的標準定義術語。


ODR使用的東西基本上意味着「我們需要它有一個身份」。這通常意味着有人正在參考或指向它。

如果你只需要的值的東西,這並不總是使它的ODR使用。編譯時常量的值不需要標識。

在C++中,身份基本上意味着「它實際上必須具有存儲空間」。

該標準沒有說「它是ODR使用,如果我們需要它有一個身份」,因爲然後不同的編譯器將有不同的規則,以確定他們需要的身份。舉個例子,如果一個操作被內聯,並且參考消失,這是否意味着它不再需要身份?

因此該標準描述了ODR使用的方法,並將其與正在使用的值區分開來。

int j = i; 

這並不需要i的身份。它只是需要它的價值。 const int i = 1;具有cannnot(在定義的行爲下)更改的值。

int const* pj = &i; 

確實需要一個身份。根據標準,i的兩個不同指針必須同意i的位置。

void foo(const int& x) { 
    int j = x; 
} 
foo(i); 

這也需要i的標識。我們參考i。儘管我們所做的唯一事情就是參考它的價值,那個參考文獻的(簡短的,理論上的)存在意味着它有一個身份。

const int a = 3; const int b = 4; 
int i = (a<2)?a:b; 

缺陷存在,這種需要ab具有同一性(它們其中ODR使用的),因爲?與所使用的規則的的相互作用。缺陷是說「我們應該解決這個問題」。

Link to DR 712

而且該決議後,是由表達,而不是他們的身份,只需要的ab的價值,所以他們並不需要有存儲。

我們關心是否有東西存儲,因爲需要存儲的東西必須有一個獨特的定義點。基本上,它們不能純粹存在於頭文件中。

請注意,對於C++ 17中的內聯變量,我們可能不太在意這一點;根據as-if規則,如果沒有人真正關注身份,則可以將創建的內聯存儲位置從存在中刪除。由於功能const&可能會「意外」強制對旨在成爲有價值代幣的事物的身份要求,這是對規則的放鬆。

+0

非常全面的答案感謝(+1) –