2016-07-06 180 views
0

#defineの有効範囲は何ですか?#defineのスコープは何ですか?

C/C++の#defineの範囲に関する質問があり、プリプロセッサを理解しようとしています。

たとえば、複数のソースファイルとヘッダーファイルを含むプロジェクトがあるとします。のは、私は次のように持っているヘッダファイルを持っているとしましょう:

// header_file.h 

#ifndef __HEADER_FILE 
#define __HEADER_FILE 

#define CONSTANT_1   1 
#define CONSTANT_2   2 

#endif 

だが、私は次の順序でコンパイルされている2つのソースファイルを持っているとしましょう:

// source1.c 

#include header_file.h 

void funct1(void) 
{ 
    int var = CONSTANT_1; 
} 


// source2.c  

#include header_file.h 

void funct2(void) 
{ 
    int var = CONSTANT_2; 
} 

私が必要な他のすべてが含まれていると仮定すると、オーバーヘッド、このコードは正常にコンパイルする必要があります。しかし、コンパイルの間に#defineが記憶されているかどうか不思議です。上記のコードをコンパイルすると、各#includeの内容は実際にインクルードされていますか、インクルードガードが実際に実装されていますか?

TLDR:1つのコンパイル単位から次のコンパイル単位まで#defineが引き継がれますか?または、#defineは1つのコンパイル単位内にのみ存在しますか?

これを入力すると、私は自分自身の質問に答えていると信じています。私は信じられた答えを述べます。 #defineは単一のコンパイル単位(.c)に制限されています。プリプロセッサは、あるコンパイル単位から次のコンパイル単位に進むときに#defineを本質的に忘れる。したがって、私が挙げた上記の例では、インクルードガードは機能しません。私はこの信念で正しいですか?

+6

TL/DR: '#define'は各コンパイル単位で、'#undef'-edまで下向きに定義されている点から見ることができます。 –

+0

[Cでの#defineプリプロセッサのスコープ](http://stackoverflow.com/questions/6379489/scope-of-define-preprocessor-in-c)の可能な複製 –

答えて

2

source1.cはsource2.cとは別にコンパイルされます。したがって、定義はsource1がコンパイルされるときに処理され、独立したアクションとして、コンパイル時にsource2に対して処理されます。

これは明確な説明です。

0

はい、あなたは正しいです! ファイルのコンパイルは、単なる実行中のプロセスに過ぎません。 1つのプロセスは、明示的に実行されない限り別のプロセスと相互作用できません。 cプリプロセッサはリテラル置換メカニズムであり、愚かな方法で実行されます。条件付きチェックが実行されても、プリプロセッサの進行中のインスタンスに限定されます。実行(コンパイル)が終了すると、何も実行されません。プリプロセッサはコンパイラを "構成"しません。そのスコープは "独自のコンパイル"まで制限されます

1

プリプロセッサマクロは "スコープ"を持たないため、コード内のマクロ。

これは、コンパイラは、文字列CONSTANT_1CONSTANT_2を見ていないが、代わりにその展開(それぞれ12)に置き換えられ、これらのマクロで前処理形式のソースを取得しないことを意味します。

-Eフラグを使用してgccを呼び出すか、特定のコンパイラで前処理するフラグだけを使用して、この前処理されたソースを調べることができます。

関連する問題