• ベストアンサー

Visual C++ 2008を使いたいのですが、#pragma onceの効果範囲って正確にはどうなっているのでしょうか?

初歩的な質問かもしれませんが、何をどう調べれば分かるのか分からないので、お願いします。 #pragma once は、まずそれを書いた、あるいは書いたことになるヘッダだけに適用されますか? また、仮にそうだとしてもこれの効果範囲はどこから始まり、どこで終わるのでしょうか?書いた行からで、最後まででしょうか? また、多重定義がエラーになる事は承知しておりますが、なぜエラーにする必要があるのでしょうか? エラーにするという事は、きっと許容すると何かまずい問題が発生してしまう可能性があるのですよね?

質問者が選んだベストアンサー

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

#2です。 先の話は変数の多重定義の話でしたが、インクルードファイルだとむしろ構造体等の型多重定義やマクロ多重定義の方ですね。 こちらは、多重定義が許容された場合に「多重定義されたものが同じ内容である保証がない」のが問題になるわけです。 例えば以下のケースが起こりえることを想定してもらえばわかりやすいかと思います。 typedef struct { int a; } A; typedef struct { double a; } A; A a; /* どっちのA? */ #define NUM 1 #define NUM 2 int a = NUM; /* aの中身は1?2? */ -- ちなみに変数の方は…… /* ↓多重宣言が許容された場合、この二つの宣言は別々のメモリにマップされてしまう */ int a; int a; a = 1; /* どっちのa見ればいいのよ? */ なお、同名の変数でも int a; { int a; a = 1; } のようにスコープが違う場合より狭いほうのスコープを使うことになっているため問題ないです。 #マクロ以外では正気でやるコーディングではないと思いますが

LongSecret
質問者

お礼

なるほど、いずれにしてもアブナイですね。 最後の「スコープが違う場合~」はまた参考になりました。 ありがとうござます。

その他の回答 (2)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

・#pragma onceのスコープ 自分ではpragmaは使わないのですが、#pragma onceを書いたファイルにだけ適用されるのではないですか。記述位置により有効範囲が変わるかどうかは試してみればすぐわかりますよね。 ・多重定義 多重定義を許容すると同じシンボル名に対する参照先が複数できてしまい、どれを参照しているのかがわからなくなってしまいます。 同じ変数にアクセスしているつもりで全く別々のものを触っていたなんてことにもなりかねず、とんでもないバグの温床になるので言語仕様レベルでエラーにしている訳です。

LongSecret
質問者

お礼

すみません、教えて!gooの利用は初めてなので、使い方を間違えました。(ということに?) お礼→補足が定石ですか。 順序を逆に書いてしまいましたが、ありがとうござます。

LongSecret
質問者

補足

「シンボル名に対する参照先が」という言葉がしっかり分からないので正確にイメージできないのですが、つまり 多重定義が仮に起こったとすると、定義するたびにその中身を格納する領域が次々に出来てしまう。 となり、同じ物が複数の場所に出来てコンピューター的にはどれにアクセスすればいいか分からなくなってしまう、そうなれば安定した動作は保証されないだろう。 という感じってことでしょうか?

noname#208124
noname#208124
回答No.1

適用先は書いたヘッダのみ 範囲は該当ファイル全部

参考URL:
http://msdn.microsoft.com/ja-jp/library/4141z1cx.aspx
LongSecret
質問者

お礼

同上です。次回以降は「お礼」の方を先に書くように気を付けます。

LongSecret
質問者

補足

非常にスカッとする回答ありがとうございます。 では、適用範囲を一部にしたい場合は #ifndef、#define、#endif の方を使って書く事になる、ということですね?

関連するQ&A