2010-11-25 20 views
11

該問題出現在答案的評論的問題Is C/C++ bool type always guaranteed to be 0 or 1 when typecast'ed to int?正在讀取一個不確定的值未定義的行爲?

有問題的代碼分配的bool(本地)陣列而不初始化它們的值。

const int n = 100; 
bool b[n]; 

很明顯,b中的值是不確定的。

一些評論者認爲閱讀例如b[0]是未定義的行爲。這是C++標準中的任何地方嗎?我仍然相信相反的:

  1. 有明確的存儲分配和基本布爾類型的初始化是完整的,因爲它沒有一個構造函數。因此,它肯定與取消引用未初始化的指針或調用未初始化的非重要對象上的方法/轉換運算符相同。這些具體情況似乎已被標準覆蓋。

  2. C:What happens to a declared, uninitialized variable in C? Does it have a value?中的行爲確實未定義,有些受訪者似乎混淆了這兩者。

  3. 在最新的C++ 0x草稿中,我找不到不確定值的定義尤其沒有定義允許訪問這樣的值來觸發處理器陷阱。事實上,Bjarne的Stroustrup的是不知道的inderminate值可能是什麼:http://zamanbakshifirst.blogspot.com/2007/02/c-indeterminate-value.html

+1

呵呵,「未定義的行爲」在StackOverflow中是一個非常喜歡的術語,它用於從定義的實現,直到未定義的實際定義。 – 2010-11-25 16:54:13

+1

我的意思是諺語中的「鼻魔」種類未定義。 – Sebastian 2010-11-25 16:57:30

回答

4

是,正式不定值的右值轉換爲UB(除unsigned char,原來我寫了「及其變體」,但我記得的正式迎合了1的補符號的字符,其中有可能減0可以作爲陷阱值)

我懶得做標準款查找適合你,也懶得計較downvotes爲

然而,實際上在(1)古老的體系結構中,也許只是一個問題(2)64位系統。

編輯:哎呀,我現在似乎記得一篇博客文章和關於正式UB訪問不確定字符的相關缺陷報告。所以也許我必須實際檢查標準的+搜索DR。呃,它將不得不在以後,現在咖啡!

EDIT2:Johannes Schaub非常友好地提供了這個link to SO question,其中討論了訪問字符的UB。所以,這就是我想起它的地方!謝謝,約翰內斯。 。

歡呼&心連心,

3

bool,標準說下3.9.1基本類型:bool類型的

值是真或假 。

隨着一個腳註:

的方式使用布爾值來描述 本國際標準如 「未定義」,例如通過檢查一個未初始化的自動 對象的 值,可能會導致它表現爲,就好像 它既不是真也不是假。

5

答案與最新的C++ 1Y工作草案(N3946),我們可以發現here這個問題的變化。部8.5初始化器段落從C++ 03和C++ 11改變了很多,現在包含以下(重點礦山):

如果對象沒有指定初始化,則對象是默認初始化的 。 當獲得用於與自動或 動態存儲持續時間的對象存儲,所述對象具有不確定 值,如果沒有初始化爲對象進行,即 對象保留一個不確定的值,直到該值被替換 (5.17)。 [注意:靜態或線程存儲時間爲 零初始化的對象,請參見3.6.2。 - 注完] 如果一個不確定的值是通過評估產生 ,這種行爲是未定義除了在 以下情況

,並繼續列出一些例外無符號窄字符類型只,我有一個完整的報價Has C++1y changed with respect to the use of indeterminate values and undefined behavior?

所以你的情況b具有自動存儲時間而沒有初始化,因此具有不確定的值。因此評估b[0]確實是未定義的行爲。

以前我們需要使用左值到右值轉換證明,這是不確定的,但就是因爲the conversion is underspecified問題。

注意,不確定的值本節斜體,因此這意味着它在適當的位置被限定,因此現在C++ 1Y實際上定義了術語。此前該術語沒有定義,這在defect report 616中涵蓋。

0

,閱讀一個不確定的值通常會導致不確定的行爲其實是不只是一個「理論」的問題。即使對於所有可能的位模式都具有已定義值的類型,對於不確定值的行爲方式與未指定值不同,也不應將其視爲「令人驚訝」。例如,如果* p成立不確定的值,而X是未示出的任何位置,除了 使用的,代碼:

uint32_t x,y,z; 
... 
x = *p; 
if (condition1) y=x; 
... code that "shouldn't" affect *p if its value is defined 
if (condition2) z=x; 

可以被重寫爲:

if (condition1) y=*p; 
... code that "shouldn't" affect *p if its value is defined 
if (condition2) z=*p; 

如果* p的值是不確定的是,編譯器不會禁止 讓兩個「if」語句之間的代碼修改其值。 例如,如果* p佔用的存儲在釋放並重新malloc之前被「float」 佔用,編譯器可能會在上述兩個「if」語句之間寫入「float」 值。

相關問題