2013年12月10日火曜日

Google Testとクラス定数

Google Testではまったところ。こんなテストがビルドできない。

#include <gtest/gtest.h>
#include <cstdio>
struct Foo {
    static const int A = 100;
    static const int B;
    enum {
        C = 300
    };
};
const int Foo::B = 200;
int add(int a, int b) {
    return a + b;
}
TEST(AddTest, TestA1) {
    int sum = add(21, 79);
    EXPECT_EQ(Foo::A, sum);
}
TEST(AddTest, TestA2) {
    int sum = add(33, 67);
    int exp = Foo::A;
    EXPECT_EQ(exp, sum);
}
TEST(AddTest, TestB) {
    int sum = add(123, 77);
    EXPECT_EQ(Foo::B, sum);
}
TEST(AddTest, TestC) {
    int sum = add(199, 101);
    EXPECT_EQ(Foo::C, sum);
}
int main(int argc, char *argv[]) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

上記コードのTestA1でFoo::Aが見つからんとリンカに怒られるのだが、Debianのg++ v4.7.2のコンパイル結果を見てみると、どうも最適化が中途半端なのか、EXPECT_EQマクロを展開した先ではFoo::Aがインライン展開されず、外部モジュールにあるFoo::Aを参照しているところがあった。当然そんなものは誰も定義していないので、リンクでこけるわけだ。ちなみに、MavericksのApple LLVM v5.0でも同様にTestA1は通らなかった。

Google Testのマクロの引数は、テンプレートの引数になったり何だりややこしいことになっているので、なるべくシンプルな式を与えるのが無難なのかな。

0 件のコメント:

コメントを投稿