这不是静态名称空间优越性的重复性吗?请在将其标记为重复之前仔细阅读问题。我不是问为什么使用未命名的名称空间与静态!
我问,为什么 Google Tests 放置在未命名的名称空间内?这是 Google测试遵循的一些惯例吗?如果是,为什么?无论是否处于未命名的名称空间,测试都可以正常工作,因此显然不需要。**
我从github克隆了Google测试,并为我的Mac构建了它。它可以正常工作,但是我在示例测试代码中注意到他们将测试放在未命名的名称空间中。有人知道为什么吗?
例如,请参见以下文件:googletest/googletest/samples/sample1_unittest.cc(https://github.com/google/googletest/blob/master/googletest/sampleast/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)的评论回答了这个问题,尤其是部分
您不需要询问程序员为什么不将内容放入全局名称空间中。您需要问他们为什么有。
但是,从教学上讲,我认为这是一个好主意,以一个恐怖的例子,如果人们不遵循良好的编码实践,并且由于错误而违反了ODR。
首先,要将程序与问题联系起来,需要知道一些Google测试宏创建新类。现在,考虑以下程序
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;
}
注意类MyClass
如何具有两个不同的定义。使用G 5.4.0-6ubuntu1〜16.04.10,用
g++ -O3 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined
打印 4 和 6 ,预期行为。但是,没有优化的编译和运行,即用
g++ -O0 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined
打印 4 和 3 !
现在,将此错误放入一个非平凡的程序中,您可能很容易放松一个下午的调试,尤其是如果该错误处于休眠状态一段时间时。另一方面,将类包装在匿名名称空间中,完全没有时间,并且可以防止错误。我认为这说明了某些良好的编码实践背后的基本原理之一:基本风险管理。