ページ 1 / 1
名前空間
Posted: 2008年11月30日(日) 14:13
by へろりくしょん
先日ちょっと気になるコードを目にして、色々いじってたのですが、
分からないところが出てきましたのでご教示おねがいします。
(1)
typedef struct{
...
}HOGE;
main(void)
{
HOGE HOGE;
}
(2)
typedef struct{
...
}HOGE;
HOGE HOGE;
main(void)
{
...
}
上記のような(1)、(2)のコードについて、なぜ(1)のコードが良くて、
(2)のコードがダメなのか。
よろしくお願いします。
Re:名前空間
Posted: 2008年11月30日(日) 16:24
by Justy
どちらかと言えば、名前空間というより有効範囲の問題ですね。
同一名前空間の中での、有効範囲の違いによる問題ですので。
わかりやすく言えば、関数の外で typedefで HOGEを宣言すると、ファイル有効範囲で
HOGEという名前が予約済みになります。
で、(2)は同じファイル有効範囲で宣言した HOGE HOGEは変数名が被るので
エラーになります。
しかし、(1)のように関数内でローカル変数として宣言した場合、その変数名は関数内だけの有効範囲に
なり、有効範囲が異なりますので被りません。
この有効範囲が違うということを利用すると、以下のようなコードも有効になります。
[color=#e0f0ff" size="-1" face="monospace]
#include <stdio.h>
typedef struct
{
int a;
} HOGE;
int main(void)
{
typedef struct
{
int b;
} HOGE;
HOGE h1 = { 0 };
printf("%d^n", h1.b);
{
typedef struct
{
int c;
} HOGE;
HOGE h2 = { 0 };
printf("%d^n", h2.c);
}
return 0;
}
[/color]
関数内で typedefした HOGEは、関数の外で typedefしたものとは有効範囲が異なるので、
問題なくコンパイルできます。
しかも、関数の中で、更に {}のブロックで囲った中は別の有効範囲になるので、
また別の HOGEを持つことができます。
但し、異なる有効範囲の HOGEは不可視となりますので、その中では使うことは出来きなくなります。
で、当然ですが、関数内の有効範囲でも(1)と同じように HOGE HOGEと
いうことをすれば、関数内の typedefされた HOGEと有効範囲が同じなので、同様にエラーになります。
[color=#e0f0ff" size="-1" face="monospace]
int main(void)
{
typedef struct
{
int b;
} HOGE;
HOGE HOGE = { 0 }; /* コンパイルエラーになる */
return 0;
}
[/color]