2012-10-17 11 views
11

ファイルにiostreamやその他のヘッダファイルを2回含めるとどうなるか教えてください。私はコンパイラがエラーをスローしないことを知っている。コードが2回追加されるのか、内部的に何が起こるのでしょうか?ヘッダーファイルを含めると実際に何が起こりますか?C++で2回ヘッダファイルを含む

+1

大きな助け:: http://www.cplusplus.com/forum/articles/10627/ – Abhineet

答えて

10

Include guardは、ファイルの内容がコンパイラによって実際に2回見られるのを防ぎます。あなたは2回マクロSOME_STRING_Hラウンド初めてのファイルが含まれている場合ので、定義されておらず、今

#ifndef SOME_STRING_H 
#define SOME_STRING_H 

//... 

#endif 

ガードは基本的に、ヘッダファイルの最初と最後にプリプロセッサの条件付きディレクティブのセットです含めますファイルの内容が処理され、コンパイラに表示されます。しかし、#ifdefの後の最初のものは#defineであるので、SOME_STRING_Hが定義され、次回はコンパイラによってヘッダファイルの内容が見えなくなります。

衝突を避けるために、インクルードガードで使用されるマクロの名前は、ヘッダーファイルの名前に依存します。

+0

ちょうど注:マイクロソフトのツールを使用するとき、あなたはしばしば '#pragma once'を見ます。これは、同じようなfunctinalityを持っています。 '#ifndef ...'コンパイラの互換性を高めるには、後者を使用する必要があります。 – AquilaRapax

+0

また、ほとんどのコンパイラがこのパターンを認識し、ファイルを2度目に見たときにファイルを開くことさえありません。 –

+0

これは実際に質問に答えるものではありません。私は他の人のコードを見ているので、元の質問に興味があります。 – Frederick

2

これは単にため、次の行に沿ってプリプロセッサコードに、スキップされます:

#ifndef MY_HEADER_H 
#define MY_HEADER_H 

<actual header code here> 

#endif 

あなたが二回含めるのであれば、その後、MY_HEADER_Hがすでに定義されており、#ifndef#endif間のすべてがプリプロセッサによってスキップされます。

3

ヘッダーファイルは単純な獣です。 #include <header>の場合、headerの内容は基本的にファイルにコピー・ペーストされます。複数回含まれているからヘッダを停止するには、include guardsは、ほとんどのヘッダファイルにあなたはそれが依存

#ifndef SOME_HEADER_FILE_GUARD 
#define SOME_HEADER_FILE_GUARD 

//Contents of Header 

#endif 
0

に似て何かを参照してくださいよ理由である、使用されています。 <assert>を除いて、標準では、標準ヘッダーの2番目(およびそれ以降)にはノーオペレーションを含めることが必要です( )。しかし、これはヘッダの特性である です。コンパイラは( 概念的に) がインクルードに出会うたびにすべてのヘッダーテキストを読み込み、インクルードします。 のようなものに囲まれますヘッダー内のC++コードのすべて:

このような場合には複数の定義を回避するための標準的な実践が使用警備員を含めること で明らかに

#ifndef SPECIAL_NAME 
#define SPECIAL_NAME 
// All of the C++ code here 
#endif SPECIAL_NAME 

、各ヘッダが必要別の名前。アプリケーション内では、通常 というファイル名と の場所に基づいて規則を確立できます。 subsystem_filenameのようなもので、 の文字はマップされています(大抵は大文字のものがほとんどです)。C++シンボルで正しくありません( のファイル名で使用している場合)。 ライブラリの場合、適切な長さの文字列をランダムに生成するのがベストプラクティスです。 (確かに が実装の品質の観点から劣っていますが) のすべての記号が文書化された接頭辞で始まることを保証することです。

システムライブラリは、もちろん、予約されたシンボル(例:記号 はアンダースコアで始まり大文字で始まります)ここでは には矛盾がないことが保証されています。あるいは、実装に依存する別の手法である を完全に使用することもできます。たとえば、 は、コンパイラ拡張子#pragma onceを使用します。 g ++はインクルードガードを使用します。 は常に_GLIBCXXで始まります(これはユーザコードの正当なシンボルではありません)。 これらのオプションは必ずしも利用可能なわけではありません。

関連する問題