2

私が抱えている問題は、次のコードに示されています。

#include <iostream>

#define X 4

int main()
{

    std::cout << "should be 4: " << X << std::endl;
#define Y X + 4
    std::cout << "should be 8: " << Y << std::endl;

#undef Y
#define Y X+0
#undef X
#define X Y+1

    std::cout << "expecting 5: " << X << std::endl;
}

エラー:

test2.cc: In function ‘int main()’:
test2.cc:17: error: ‘X’ was not declared in this scope

私がエミュレートしようとしているパターンは、コード/ビルド レベルでプログラムを拡張することです ( nginxモジュールがコンパイル時に配線される方法とよく似ています)。ビルドに s を追加することで拡張可能 (プラグ可能) な拡張可能なコンパイル時構造を構築する必要があり#includeます。これにより、すべてのプラグインを含む一意の名前を持つ boost-mpl-vector が生成されます。したがって、が一意の終了名である場合、X_0、X_1、X_2 は、ベクトルに mpl-vectorが適用されているXため、途中で構築される名前です。push_back

boost:: preprocessorの抽象化が重要であることはわかっていますが、最終的にコンパイル時にモジュール化されるシステムの一部を試作しているため、まだ調査に時間を費やしたくありません。

というわけで、今後の参考までに

  1. 上記のエラーが表示されるのはなぜですか?
  2. 正しい生のプリプロセッサ パターンはどのように見えるべきか。
  3. 正しいブースト プリプロセッサ ライブラリ パターンはどのように見えますか。
4

3 に答える 3

5

g++ -E でコンパイルすると、次のようになります。

int main()
{

    std::cout << "should be 4: " << 4 << std::endl;

    std::cout << "should be 8: " << 4 + 4 << std::endl;






    std::cout << "expecting 5: " << X+0 +1 << std::endl;
}

これで、エラーが発生する理由がわかります。

于 2011-04-08T09:19:53.040 に答える
4

名前空間を使用して、一石二鳥にしてみませんか。

// a.hpp:

namespace a {
    const int module_id = 0;

    class module_a : extension_module< module_id > { … };
}

#undef last_module
#define last_module a

// b.hpp:

namespace b {
    const int last = last_module::module_id + 1;

    class module_b : extension_module< module_id > { … };
}

#undef last_module
#define last_module b

これはあまり「賢く」なく、ID の痕跡を残します。

ただし、ODR を機能させるには、モジュールを毎回同じ順序で含める必要があります。

私は鳥を殺すことを主張していません。

于 2011-04-08T09:15:32.490 に答える
2

コード サンプルの問題は、X マクロと Y マクロに循環依存関係があることです。

Y は X+0 として定義され、X は Y+1 として定義されます。したがって、マクロが展開されると (X を使用する時点で発生します)、問題が発生します。

追加:

動作は次のようです: 定義名 X 内でマクロを展開するXと、プリプロセッサの名前空間で定義されていないため、X+0+1 が X 展開として表示されます。

于 2011-04-08T09:26:36.803 に答える