2012-04-27 34 views
0

我的問題是關於statement expressions,其中加入作爲在GNU C.擴展考慮下面的代碼:在語句表達式中'重新定義'變量是否安全?

#include <stdlib.h> 
#include <stdio.h> 

int main(void) 
{ 
    int i = 0; 
    printf("%d\n", i); 

    {int i = 1;printf("%d\n", i);} 

    printf("%d\n", i); 
    return EXIT_SUCCESS; 
} 

編譯(gcc -Wall -std=gnu99 lala.c -o lala)和運行將產生:

0 
1 
0 

這種做法(使用)是相當普遍的,特別是在Linux內核的container_of中:

#define container_of(ptr, type, member) ({ \ 
       const typeof(((type *)0)->member) *__mptr = (ptr); 
       (type *)((char *)__mptr - offsetof(type,member));}) 

類似於這種情況,我想定義一個宏來聲明一個局部變量並用它做一些事情。但是,我想這樣做而不會污染當前範圍內可用的變量名稱,並避免可能的重新定義。我無法在文檔中找到有關重新定義情況下確定範圍的確切信息。

在上述情況下,編譯器不會發出有關重新定義的警告。我的問題是,我是否可以依賴這樣一個事實,即在語句表達式中的變量作用域不會影響外部作用域中相同名稱的變量?

+0

什麼是不允許的聲明變量,其名稱以兩個影響變量下劃線。 – dreamlax 2012-04-27 12:50:09

+2

是不是你的使用只是一個複合語句?因爲它是一個語句表達式,它必須根據鏈接的文檔括在括號中 – msam 2012-04-27 12:55:28

+0

@msam:是的,但我想用括號定義一個宏 – 2012-04-27 12:58:20

回答

2

當然,這是安全的,這是作出的範圍。

(正如dreamlax表示他的意見,以兩個下劃線的標識符保留爲實現(編譯器,庫,託管environement ...),所以你不應該使用它們。)

+0

正確,愚蠢的問題:P我應該擁有的關鍵字衆所周知的是'陰影變量',這令我驚訝的是之前沒有遇到過(可能是因爲一般人會避免它們)。 – 2012-04-27 13:14:07

0

關於範圍

從3.1.2.1 ANSI C(在C99類似6.2.1):

如果聲明瞭標識符聲明符或 類型說明符塊或 內出現的參數聲明列表內的功能DEFI定義, 標識符具有塊範圍,其終止於}封閉 相關的塊

...

如果外 聲明一個詞法相同標識符的在同一 存在名稱空間,直到當前作用域終止時纔會隱藏,在 之後,它再次變爲可見。

因此,假如編譯器兼容,你應該能夠使你的假設,即在表達式內範圍的變量不會在外部範圍

+0

只發布了上面的答案,因爲它太長而無法成爲評論 – msam 2012-04-27 13:13:49

相關問題