1

I've recently discovered some strangeness with this setup (clang & gtest) and duplicate names (demonstrated in example below). No compiler warnings / errors are generated but some kind of 'type swapping' appears to be occurring at runtime. I may be programming in a way which produces 'undefined behaviour'.

Example:

main.cpp:
#include "gtest/gtest.h"
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

test_a.cpp
#include <boost/optional.hpp>
#include "gtest/gtest.h"
namespace test { 
class TestA : public ::testing::Test {
}; 
struct Param {
  boost::optional<int> x_;
  boost::optional<int> y_;
  int sum_;
}; 
class TestAWithParam :
    public TestA,
    public ::testing::WithParamInterface<Param> {}; 
TEST_P(TestAWithParam, Param) {
  const auto p = GetParam();
  ASSERT_TRUE(p.x_ && p.y_);
  EXPECT_EQ(p.sum_, *p.x_ + *p.y_);
} 
INSTANTIATE_TEST_CASE_P(
    All,
    TestAWithParam,
    ::testing::Values(
        Param{1, 2, 3},
        Param{2, 3, 5},
        Param{3, 4, 7}));
}  // namespace test

test_b.cpp
#include "gtest/gtest.h"
namespace test {
class TestB : public ::testing::Test {};
struct Param {
  int x_; 
  int y_; 
};
class TestBWithParam :
    public TestB,
    public ::testing::WithParamInterface<Param> {}; 
TEST_P(TestBWithParam, Param) {
  const auto p = GetParam();
  EXPECT_EQ(p.x_, p.y_);
}
INSTANTIATE_TEST_CASE_P(
    All,
    TestBWithParam,
    ::testing::Values(
      Param{1, 1}, 
      Param{2, 2}, 
      Param{3, 3}));
}  // namespace test

I've reduced spacing to shorten the code - so don't stress, I don't actually write code like that :P

The test application fails with a segmentation fault.

If I rename one of the Param structures (such that the duplicate naming no longer exists), the test program runs fine with no failed tests.

Note that I've experienced similar UB with 'non-parameterised' tests - so I wouldn't say this is a TEST_P issue.

Any help would be greatly appreciated :)

Thanks.

user3513346
  • 117
  • 8
  • You're violating the one definition rule by defining two different `Param` classes in the `test` namespace. – user657267 Aug 27 '14 at 06:41
  • possible duplicate of [What exactly is One Definition Rule in C++?](http://stackoverflow.com/questions/4192170/what-exactly-is-one-definition-rule-in-c) – user657267 Aug 27 '14 at 06:42
  • Thanks :) Any reason why the compiler / linker can't pick this up? – user3513346 Aug 27 '14 at 07:04
  • Also, any suggestions on how I can avoid this problem? I could introduce a unique namespace to each test file, but is there a better way? The lack of compiler warning / error is concerning. How do people usually try and protected from this? – user3513346 Aug 27 '14 at 07:08
  • The compiler won't pick it up because the standard doesn't mandate anything (`no diagnostic required.`). You can use an anonymous namespace to contain classes that aren't part of your interface (`namespace {}`), anything defined in an anonymous namespace is only visible to its own translation unit. – user657267 Aug 27 '14 at 07:17

0 Answers0