4

ヘッダーとソースファイルで定義されている次のマクロに遭遇したとき、プログラム内のコンパイルとリンクの問題を調査していました。

/* file_A.c */
#ifndef _NVSize    
   #define _NVSize 1
#endif

/* file_B.c */
#include "My_Header.h"
#ifndef _NVSize    
   #define _NVSize 1
#endif

/* My_Header.h */
#define _NVSize 1024

GCC出力マップファイルに次の情報が表示されるまで、まだ異常なことはありません。

/* My Map File */
...
.rodata  0x08015694   _NVSize
...

マップファイルについての私の理解は、マップファイルの.rodataセクションにシンボルが表示されている場合、このシンボルはコンパイラによってグローバル変数として扱われているということです。ただし、コンパイラがファイルを解析する前にマクロをプリプロセッサで処理する必要があるため、これは当てはまりません。このマクロは、コンパイルする前に、定義された値に置き換える必要があります。

これはGCCがマクロを処理する標準的な方法ですか、それともGCCがこれをグローバル(デバッグ設定の可能性があります)として扱う実装固有の理由がありますか?また、マクロが別のソースファイルで再定義された場合、これはどういう意味ですか?単一のソースファイルに対して再定義しただけですか、それともグローバル変数を変更して、プログラム内で使用されているすべての場所で_NVSizeを変更しましたか?

4

2 に答える 2

3

コンパイラは、テキスト置換を行った場合とまったく同じ結果が得られることを保証する限り、マクロをグローバル変数に自由に割り当てることができると思います。

コンパイル中に、コンパイラはこのグローバルを特別にマークして、マクロ定数値であることを示すことができるため、再割り当てやアドレ​​スの取得などはできません。

ソースでマクロを再定義すると、コンパイラはこの変換を実行しない可能性があります(そして、期待どおりに処理します:コンパイル前のテキスト置換)、異なる値の1つで実行します(またはすべての値で、発生ごとに異なる名前を使用する)、または他の方法でドメッシングを行う:)

于 2012-04-15T12:18:51.390 に答える
1

マクロはプリプロセッサステップで置換され、コンパイラは置換された結果のみを確認します。したがって、マクロ名が表示された場合、私の賭けは、マクロが使用時に定義されていなかったことです。これは、特定の#define _NVSizeとの間で定義され#undef _NVSizeます。最初のマクロを使用せずに既存のマクロを再定義する#undefと、プリプロセッサエラーAFAIRが発生するはずです。

ところで、マクロ名はアンダースコアで始めるべきではありません。これらは実装用に予約されています。

于 2012-04-15T13:02:57.777 に答える