2014-01-08 68 views
5

我有一段代碼,當我寫它以這種形式(與-Wjump-misses-init標誌),編譯罰款:爲什麼GCC給我-Wjump-misses-init警告?

int some_function(void) { 

     ... 

     if (is_error) 
       goto error; 

     int a; 

     a = 1; 

     return a; 

error: 
     return 666; 
} 

但是,當我寫相同的功能以這種形式,我得到了下面的警告當我編譯(?:

int some_function(void) { 

     ... 

     if (is_error) 
       goto error; 

     int a = 1; 

     return a; 

error: 
     return 666; 
} 

test.c: In function 'some_function': 
test.c:15:17: warning: jump skips variable initialization [-Wjump-misses-init] 
test.c:21:1: note: label 'error' defined here 
test.c:17:13: note: 'a' declared here 

爲什麼GCC給我的警告,當我宣佈並在同一行初始化a似乎有點奇怪我這些例子是荒謬的,但我怕我不能隨意?泄露真實的代碼片段我在Debian Wheezy 7.3上運行GCC 4.7.2。

編輯:無效錯字

+2

在C++中[你不允許通過初始化跳過聲明](http://stackoverflow.com/questions/20963288/c-conditional-storage-allocation-for-object-caused-by-scope/20963326 #20963326)但我無法在C99中找到相同的語句。 –

+0

我不知道錯誤是否適用於不同的優化標誌。或者如果組件不同。也許在一種情況下,操作順序略有不同。這只是一個瘋狂的猜測。 – luk32

+0

另外,'int void'看起來是一個錯字。 –

回答

2

C++你不準bypasses declarations with initialization但似乎在C99就可以了。如果您使用-Wjump-misses-init-Wc++-compat,您可以讓gcc提醒您。這是包括在gcc文檔部分 Options to Request or Suppress Warnings說:

警告如果goto語句或switch語句向前跳跨變量的初始化,或變量已被初始化之後向後跳轉到一個標籤。這隻會對在聲明時初始化的變量發出警告。此警告僅支持C和Objective-C;在C++中,這種分支在任何情況下都是錯誤的。

-Wjump-misses-init包含在-WC++ - compat中。它可以通過-Wno-jump-misses-init選項禁用。

注意,這也適用於開關聲明中的聲明。解決此問題的一種方法是使用{}創建新範圍。

附件一draft C99 standard表明,這種警告,它說:

實現可以產生在其中沒有一個 指定爲該國際標準的一部分很多情況下,警告。以下是一些更常見的情況。

,幷包括以下子彈:

與具有自動存儲持續時間的對象的初始化塊跳躍 到(6.2.4)。

+0

有趣的是,'-Wjump-misses-init'不在'-WC++ - compat'中,用於我的gcc版本(4.8 .1,Ubuntu 12.04)。它已被刪除? – ecatmur

+0

@ecatmur hmmm,雖然'4.7'仍然有它,但似乎在'4.8'中是如此。 –

1

如果你跳到error:標籤後繼續使用a變量,它的價值將是不確定的(6.2.4p6);這可能會讓人困惑,這就是gcc爲什麼會提出警告。 (這在C++中也是非法的。)

爲了避免該警告並仍然使用聲明初始化,您可以在一個塊包裝代碼:

int some_function(void) { 
    { 
     ... 

     if (is_error) 
       goto error; 

     int a = 1; 

     return a; 
    } 
error: 
    return 666; 
} 

在這種情況下,你需要外塊聲明後你使用任何變量error:標籤。