2

この capnp コードに問題があります:

struct Result(Success, Error) {
    union {
        success @0 :Success;
        error   @1 :Error;
    }
}

次のように c++ ソースを作成してコンパイルしました。

capnp compile -oc++ test.capnp
g++ -o test.capnp.o test.capnp.c++ `pkg-config --cflags capnp` -std=c++11

そして、生成されたヘッダー ファイルの複数の場所で、この同じエラー (および SUCCESS ではなく ERROR と同じ) が発生しています。

error: type/value mismatch at argument 2 in template parameter list for ‘template<class Success, class Error> struct Result’
   KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
   ^
error:   expected a type, got ‘true’
error: expected primary-expression before ‘&gt;’ token
   KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
                                               ^
error: ‘::SUCCESS’ has not been declared
   KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
                                                ^

以下は、g++ が不平を言う定義の 1 つです。

template <typename Success, typename Error>
inline  ::capnp::ReaderFor<Success> Result<Success, Error>::Reader::getSuccess() const {
  KJ_IREQUIRE(which() == Result<Success, Error>::SUCCESS,
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers<Success>::get(
      _reader.getPointerField(0 * ::capnp::POINTERS));
}

g++ がこれを受け入れない理由が本当にわかりません...

capnproto 0.5.3 (最初にこの問題が発生したのは 0.5.2 で、それが役立つかどうかを確認するために更新されました) と g++ 4.9.2 を使用しています。

4

1 に答える 1

2

この回答の残りの部分は古くなっています。capnp バージョン 0.6.0 以降、この問題は発生しなくなりました。


質問を書き終えたとき、これもclangでテストしたかったので、実際にエラーを見つけました。すでに書き終わっていたので、質問を投稿することにしました。問題はKJ_IREQUIREマクロであり、マクロはプリプロセッサが処理するものであるため、そのセマンティクスは非常に醜いです。のテンプレート引数のカンマはResult、マクロの引数区切り文字として解釈されるため、g++ ではこの本当に役に立たないエラー メッセージが表示されますが、clang ではより適切なエラー メッセージが表示されます。

これを回避するには、 の引数を別のブラケット セットで囲みますKJ_IREQUIRE。このドキュメントが誰かの役に立てば幸いです。

于 2015-08-14T13:28:29.663 に答える