0

私の質問は、 GNUCの拡張機能として追加されたステートメント式に関するものです。次のコードについて考えてみます。

#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

container_ofこの方法(拡張機能の使用)は、特にLinuxカーネルではかなり一般的です。

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

この場合と同様に、ローカル変数を宣言してそれを使って何かを行うマクロを定義したいと思います。ただし、現在のスコープで使用可能な変数名を汚染せずにこれを実行し、再定義の可能性を回避したいと思います。再定義の場合にスコープがどのように正確に発生するかについてのドキュメント情報を見つけることができませんでした。

上記の場合、再定義に関してコンパイラから警告は発行されません。私の質問は、ステートメント式の内部でスコープされた変数が外部スコープの同じ名前の変数に影響を与えないという事実に頼ることができるかどうかです。

4

2 に答える 2

2

確かにこれは安全です。これがスコープの目的です。

(そして、dreamlax がコメントで示しているように、2 つのアンダースコアを含む識別子は実装 (コンパイラ、ライブラリ、ホスティング環境など) 用に予約されているため、使用しないでください。)

于 2012-04-27T12:53:07.927 に答える
0

対象範囲について

3.1.2.1 ANSI C (C99 の 6.2.1 と同様) から:

識別子を宣言する宣言子または型指定子がブロック内または関数定義のパラメーター宣言のリスト内にある場合、識別子にはブロック スコープがあり、関連するブロックを閉じる } で終了します。

...

字句的に同一の識別子の外部宣言が同じ名前空間に存在する場合、現在のスコープが終了するまで非表示になり、その後再び表示されます。

したがって、コンパイラが準拠していると仮定すると、式内のスコープの変数が外側のスコープの変数に影響を与えないという仮定を立てることができるはずです

于 2012-04-27T13:12:33.947 に答える