c++googletestgcov

Why are two destructors created for googletest test fixture when not placed in unnamed namespace?


When I analyze gcov results for the following code (after using c++filt to demangle), I see two FooTest::~FooTest() in the coverage information file, both mapped to the same line number. One is marked as called and the other is not. Note: No compiler optimizations are used (i.e. -O0).

#include "gtest/gtest.h"
struct FooTest : ::testing::Test {
    ~FooTest() = default;
};
TEST_F(FooTest, run) {}
int main(int argc, char* argv[]) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

If I put the declaration of FooTest in the unnamed namespace, I only see 1 destructor (anonymous namespace)::FooTest::~FooTest() in the coverage info.

#include "gtest/gtest.h"
namespace {
struct FooTest : ::testing::Test {
    ~FooTest() = default;
};
}
TEST_F(FooTest, run) {}
int main(int argc, char* argv[]) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

I realize that the visibility of FooTest is different when placed in the unnamed namespace. But, I wouldn't have expected that to cause the difference since the translation unit is compiled without optimizations.

What precisely is happening to cause gcov to report two destructors with the same signature to exist when the test fixture is not placed in the unnamed namespace?


Solution

  • The link posted by Eljay, https://stackoverflow.com/a/6614369/4641116, contains an explanation as to why multiple dtors are created.

    In the code snippit above, the base object destructor (D2) is called by the derived test class defined via the TEST_F macro. The deleting destructor (D0) is not called by the program and hence not reported as covered by GCOV.

    When the class has default visibility, the compiler cannot prove that no one outside the translation unit might require the deleting destructor, which is why it is created.