为什么 google 测试样本将测试放在匿名命名空间中?

Why does google test sample put tests in an anonymous namespace?

这不是 Superiority of unnamed namespace over static? 的副本 在将问题标记为重复之前,请仔细阅读问题。我不是问为什么使用未命名的命名空间而不是静态的!
我在问,为什么 google tests 放在未命名的命名空间中?这是 google 测试 遵循的某种约定吗?如果是,为什么?无论是否在未命名的命名空间中,测试都可以正常工作,因此显然不需要。**

我从 github 克隆了 google 测试并为我的 mac 构建了它。它工作正常,但我注意到在他们提供的示例测试代码中,他们将测试放在未命名的命名空间中。有谁知道为什么?

例如,参见以下文件: googletest/googletest/samples/sample1_unittest.cc (https://github.com/google/googletest/blob/master/googletest/samples/sample1_unittest.cc#L41)

部分文件如下所示:

// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
//
// Don't forget gtest.h, which declares the testing framework.

#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
namespace {

// Step 2. Use the TEST macro to define your tests.
...
TEST(FactorialTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
}
...
}  // namespace

有谁知道为什么所有测试都在未命名的命名空间中? 我尝试删除未命名的命名空间,示例仍然运行良好,因此显然对于这个特定示例来说没有必要。

我认为 Mike Kinghan 的评论回答了问题,尤其是

部分

You don't need to ask a programmer why haven't put stuff into the global namespace. You need to ask why they have.

但是,我认为从教学的角度来说,举一个例子说明如果不遵循良好的编码习惯并因此错误地违反 ODR 可能会发生的恐怖事件是个好主意.

首先,为了将下面的程序与问题联系起来,需要知道一些 Google 测试宏会创建新的 classes。现在,考虑以下程序

myClass1.h

#ifndef MYCLASS1_H
#define MYCLASS1_H

int f();    

#endif  /* MYCLASS1_H */

myClass2.h

#ifndef MYCLASS2_H
#define MYCLASS2_H

int g();    

#endif  /* MYCLASS2_H */

myClass1.cpp

#include "myClass1.h"

class MyClass {
public:
    void twice() { val *= 2; }
    char val;
};    

int f() {
    MyClass x;
    x.val = 2;
    x.twice();
    return x.val;
}

myClass2.cpp

#include "myClass2.h"

class MyClass {
public:
    void twice() { val *= 2; }
    double val;
};    

int g() {
    MyClass x;
    x.val = 3;
    x.twice();
    return x.val;
}

main.cpp

#include <iostream>
#include "myClass1.h"
#include "myClass2.h"

int main() {
    std::cerr << f() << std::endl << g() << std::endl;
    return 0;
}

请注意 class MyClass 有两个不同的定义。使用 g++ 5.4.0-6ubuntu1~16.04.10,编译和 运行 程序

g++ -O3 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined

打印 46,这是预期的行为。但是,编译 运行 没有优化,即

g++ -O0 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined

打印 43!

现在,将这个 bug 放入一个重要的程序中,您可能会很容易地浪费一个下午的调试时间,尤其是当 bug 隐藏了一段时间的时候。另一方面,预先将 classes 包装在匿名名称空间中根本不需要时间,并且可以防止错误。我认为这说明了一些良好编码实践背后的基本原理之一:基本风险管理。