2011-03-27 101 views
19
#include <iostream> 

int main(int argc, char** args) { 
    int foo = foo + 4; 
    std::cout << foo << std::endl; 
} 

而後續問題,是否有編譯器標誌來阻止這種事情?我發現 - 有時候牆有效,更好的辦法是完全防止它。這是什麼意思? int foo = foo + 4;

My compiler: 
g++ -v 
Using built-in specs. 
Target: i486-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu 
Thread model: posix 
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 
+1

一個編譯器標誌停止什麼樣的事情? – tkerwin 2011-03-27 16:46:13

+1

你的問題到底是什麼?你爲什麼不初始化foo? – mbx 2011-03-27 16:46:32

+0

'int foo = foo + 4;'並不意味着什麼。你寫的時候是什麼意思? – 2011-03-27 16:46:54

回答

30

不,沒有保證的辦法來阻止這類事情。它是C++和C的組成部分,變量的名稱在其初始化程序中可見。它允許你做這樣的事情

T *t = malloc(sizeof(*t)); 

有列出需要在簡單的情況下診斷的C++問題一個問題的報告,但目前的編譯器不需要診斷你的情況。

這也是有效的in a different context

編輯:澄清 - 您的代碼段的行爲未定義:您正在讀取未初始化變量的值。這些編譯器不需要診斷,並不意味着行爲被定義。

+0

這是有道理的。我必須等待8分鐘才能接受.... – Eric 2011-03-27 16:50:23

+3

+1,總是從litb學習新東西! – Xeo 2011-03-27 16:51:46

3

我敢打賭,這意味着未定義的行爲。

編輯:請參閱answer to another question的引文。

編輯:最有可能的是,RHS中的值取自堆棧中未初始化的內存位置,將4添加到堆棧中,並將結果用於初始化。

+0

@downvoter:謹慎解釋? – Vlad 2011-03-27 16:48:52

+0

@Nawaz:這並沒有說出答案中的錯誤。順便說一句,我提供的鏈接引用證明答案是正確的。 – Vlad 2011-03-27 16:53:11

+0

@Vlad:嗯..你說得對。我試圖撤銷我的downvote,但爲此你必須編輯你的帖子,因爲它不會讓我撤消! – Nawaz 2011-03-27 16:58:09

6
int foo = foo + 4; 

這是未定義的行爲。一些編譯器歸零自動的空間爲本地變量時,其他人可能不會,所以富可能包含堆的垃圾

+0

@downvoter:解釋你的downvote – BlackBear 2011-03-27 16:49:41

+0

@Nawaz:@ Johannes的回答說對了這個:未定義的行爲 – BlackBear 2011-03-27 16:55:21

+0

@BlackBear:嗯..你是對的。我試圖撤銷我的downvote,但爲此你必須編輯你的帖子,因爲它不會讓我撤消! – Nawaz 2011-03-27 16:58:27

0

我希望任何中途像樣的編譯器發出的INT FOO警告= FOO + 4;其默認配置爲。好的人可以選擇完全拒絕它作爲「使用未初始化的變量」和/或接受任何特定的發生,在程序員明確知道發生了什麼並且不關心意外行爲的情況下。

我例如經常用來寫INT撥動=切換^ 1回來時,編譯器不那麼挑剔,如果所有我想要的是一個撥動開關,我並不在乎它是否啓動TRUE或天假。現在我可能會寫static bool toggle = TRUE;切換= ^切換

2

要想從海灣合作委員會的警告對於這個特殊的代碼,你需要-Wuninitialized-Wall包括本)-O(或以上0任何優化級)。

原因是gcc無法診斷未初始化變量的使用,除非它進行數據流分析,並且在優化禁用時不會執行數據流分析。優化在默認情況下被禁用。

相關問題