1. ホーム
  2. C

C/C++の再定義

2022-02-14 22:34:31

ヘッダーファイルに次の2行の同じコードを書きなさい。

typedef int X;

typedef int X;

gccコンパイルではtypedef 'X'の再定義がすぐに報告されますが、g++では実際には何も起こりません、不思議でしょう?そこで、ドキュメントを見てみると、C++ではこんな記述がありました: " In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type that already refers. " さて、C++はクラス以外の場合にも寛容で、次のようにエラーが出るようですね。

class A{ <未定義

typedef int Y;

typedef int Y;

};

残念ながら、C 規格を見回った結果、再定義に関する明確な記述はなく、他のすべての C コンパイラがエラーを報告するかどうかはわかりません。

そこでマクロを思いつき、以下の3つのケースを試してみました。

ケース1.#define M 1

    #define M 1

ケース2 #define M(x) x++

#define M(x) x++

ケース3 #define M(x) (x+1)

#define M(x) (x + 1)

gcc/g++のコンパイル結果(ここでは実際にはプリプロセッサcc1/cc1plusと言うべき)も同じで、Case1/2はOK、Case3はエラーが報告されます。規格を確認すると、このように記述されています。

<スパン (1) 2つの置換リストは、両者の前処理トークンが同じ数、順序、スペル、空白の区切りを持つ場合にのみ同一であり、空白の区切りはすべて同一とみなされます。

(2) オブジェクトライクマクロとして定義されている識別子は、2番目の定義がオブジェクトライクマクロの定義であり、かつ2つの置換リストが同一でない限り、他の#define前処理指令によって再定義されてはならない。 同様に、現在関数型マクロとして定義されている識別子を他の#define前処理指令によって再定義してもならないが、その2番目の定義は、オブジェクトライクマクロの定義である必要がある。ただし、2 つ目の定義が関数ライクマクロの定義で、パラメータの数とスペルが同じであり、2 つの置換リストが同じである場合は、この限りでありません。

を同一とする。

ここで重要なのは、2つのテキスト(空白を含めて同一)がある場合のみ

http://hi.baidu.com/zhuxiaoyin/blog/item/f603f58e2e1321e2f11f3656.html