我只是偶然發現了這讓我吃驚行爲:在初始化中使用新聲明的變量(int x = x + 1)?
當寫:
int x = x+1;
在C/C++
- 程序(或甚至更復雜的表達式涉及到新創建的變量x)我的gcc /克+ +編譯沒有錯誤。在上面的情況中,X之後是1。請注意,前一個聲明中沒有變量x的範圍。
所以我想知道這是否是正確的行爲(甚至可能在某些情況下是有用的)與一般我的gcc版本或GCC或只是一個解析器特徵模擬。
BTW:下不起作用:
int x++;
我只是偶然發現了這讓我吃驚行爲:在初始化中使用新聲明的變量(int x = x + 1)?
當寫:
int x = x+1;
在C/C++
- 程序(或甚至更復雜的表達式涉及到新創建的變量x)我的gcc /克+ +編譯沒有錯誤。在上面的情況中,X之後是1。請注意,前一個聲明中沒有變量x的範圍。
所以我想知道這是否是正確的行爲(甚至可能在某些情況下是有用的)與一般我的gcc版本或GCC或只是一個解析器特徵模擬。
BTW:下不起作用:
int x++;
隨着表達:
int x = x + 1;
變量x
開始存在於=
標誌,這就是爲什麼你可以在右側使用它。通過「成立」,我的意思是存在變量,但尚未由初始化部分賦值。但是,除非您使用靜態存儲持續時間(例如,函數外部)初始化變量,否則它是未定義的行爲,因爲存在的x
具有任意值。
C++ 03有這樣一段話:
申報的名點立即爲它的完整說明符(第8條)後,和它的初始化(如果有的話)之前...
實施例:
int x = 12;
{ int x = x; }
這裏第二個x初始化與它自己的(不確定的)值。
第二種情況幾乎與你的問題一樣。
「成立」似乎有點模糊。我想它已經在'='之前聲明瞭,否則編譯器會抱怨使用未知的標識符。但是初始化確實發生在'='處。 – hirschhornsalz 2012-03-22 10:17:44
@drhirsch,我不認爲它含糊不清,我在標準中加入了這一點來說明這一點。 – paxdiablo 2012-03-22 10:28:13
我在評論中的第二句話是無稽之談(或非常糟糕的措詞)。我指的是用作「聲明點」的短語「成立」。它可以被理解爲「初始化點」,這將是錯誤的。 – hirschhornsalz 2012-03-22 11:07:55
它不是,它是未定義行爲。
您使用的是未初始化的變量 - x
。你得到純粹的運氣1
,任何事情都可能發生。
僅供參考,以MSVS我得到一個警告:
警告1個警告C4700:未初始化的局部變量 '我' 用
此外,在運行時,我得到一個異常,那麼這絕對不安全。
在第一種情況下,您只需使用已存在於變量所在內存位置的值。在你的情況下,這似乎是零,但它可以是任何東西。使用這樣的結構是災難性的,並且很難在未來找到缺陷。
對於第二種情況,這只是一個語法錯誤。你不能混合一個表達式和一個像這樣的變量聲明。
int x = x + 1;
基本上
int x;
x = x + 1;
你剛剛被幸運x
有0。
int x++;
但是在C++中,在解析器級別是不可能的!以前可能會被解析,但語義錯誤。第二個甚至不能被解析。
這是未定義的行爲,編譯器至少應該發出警告。嘗試使用g++ -ansi ...
進行編譯。第二個例子只是一個語法錯誤。
-ansi不會改變情況:) – 2012-03-22 10:56:45
變量從「=」上,所以它是有效的,並且當它是全局定義的,它被初始化爲零,所以在這種情況下,它被定義的行爲,在其他的變量被unintialized作爲這樣定義的仍然是單元化的(但是增加了1)。
注意它仍然不是很理智或有用的代碼。
3.3.1聲明1聲明瞭名稱的點的點立即是其完整的說明符(第8節)之後和其 初始化之前(如果有的話),不同之處如下所述。 [例如:int x = 12; {x} {x = x; }這裏第二個x用它自己的 (不確定)值進行初始化。例如末端]
上述狀態所以,應該有不確定的值,你是幸運的以1
您的代碼有兩個possiblities:
x
是一個局部變量,你具有未定義的行爲,因爲您在生命週期開始之前使用對象的值。x
具有靜態或線程本地的壽命,它是預先初始化爲零,而你的靜態初始化將可靠地將它設置爲1
。這是明確的。
我相信X是過得去的gcc初始化爲0,但你不能依賴這種行爲,因爲該標準不要求爲。它可能會在一些系統中導致垃圾。 – vidit 2012-03-22 10:09:22
@EdHeal:沒有我沒有啓用警告,也沒有啓用--ansi,但都沒有改變情況(沒有發出警告) – 2012-03-22 10:56:04
有一個相關的,合法的(但不尋常的)用法:'Node simpleGraph = Node(&simpleGraph) ;'創建一個節點與自身週期性鏈接的圖。或者甚至更大,'int x = sizeof(x);'。 – MSalters 2012-03-22 12:08:26