C++ 为什么链接顺序会影响使用宏的测试结果?
我正在使用GoogleTest和GoogleMock使用测试驱动开发来编写代码。我正在为谷歌测试写一个小插件。为了确保测试在出现正确消息时会失败,我创建了一个简单的C++ 为什么链接顺序会影响使用宏的测试结果?,c++,linker,c-preprocessor,googletest,googlemock,C++,Linker,C Preprocessor,Googletest,Googlemock,我正在使用GoogleTest和GoogleMock使用测试驱动开发来编写代码。我正在为谷歌测试写一个小插件。为了确保测试在出现正确消息时会失败,我创建了一个简单的FailureReporter类,我将该类作为子类,并在插件中注入模拟版本以捕获结果并与预期值进行比较 本着TDD极端主义的精神,我还编写了一个测试来确保FailureReporter工作正常。为此,我“替换”了FAIL()。然而,这就是事情变得奇怪的地方。它在一台机器上工作,但在另一台机器上不工作。在查找原因时,我发现可以通过更改链
FailureReporter
类,我将该类作为子类,并在插件中注入模拟版本以捕获结果并与预期值进行比较
本着TDD极端主义的精神,我还编写了一个测试来确保FailureReporter
工作正常。为此,我“替换”了FAIL()。然而,这就是事情变得奇怪的地方。它在一台机器上工作,但在另一台机器上不工作。在查找原因时,我发现可以通过更改链接顺序来修复。这似乎很奇怪,因为“修复”是使用宏完成的,我假设它在编译时是硬编码的,链接它不会有什么区别
我发现:链接测试本身不会导致任何问题。仅当在FailureReporter测试之后链接了另一个测试时,将其与使用FailureReporter模拟版本的测试链接才有效。
为什么会发生这种情况
FailureReporter.hpp:
#ifndef FAILURE_REPORTER_H
#define FAILURE_REPORTER_H
#include "gtest/gtest.h"
class FailureReporter {
public:
virtual void fail(const char* errorMessage) {
FAIL() << errorMessage;
}
};
#endif
DummyTest.cpp
#include "gtest/gtest.h"
#include "MockFailureReporter.hpp"
TEST(DummyTest, dummy) {
new MockFailureReporter();
SUCCEED();
}
使用
g++ -c DummyTest.cpp
g++ -c FailureReporterTest.cpp
并将其与
g++ DummyTest.o FailureReporterTest.o -pthread -lgtest -lgmock -lgmock_main
g++ FailureReporterTest.o DummyTest.o -pthread -lgtest -lgmock -lgmock_main
生成失败failMethod测试的a.out可执行文件,同时将其链接到
g++ DummyTest.o FailureReporterTest.o -pthread -lgtest -lgmock -lgmock_main
g++ FailureReporterTest.o DummyTest.o -pthread -lgtest -lgmock -lgmock_main
生成一个a.out可执行文件,该文件成功执行两个测试。为什么?
class FailureReporter {
public:
virtual void fail(const char* errorMessage) {
/* code */
创建FailureReporter::fail
的隐式inline
实现
内联
函数被导出。如果链接器看到两个名称和类型相同的内联
函数,它将自动放弃其中一个。如果它们实际上不相同,则说明您的程序格式不正确,不需要进行诊断
当您仅在一个编译单元中重新定义FAIL()
并将其与其他编译单元链接时,您将得到FailureReporter::FAIL
的两个定义。它们相互关联,并且未定义行为结果。在您的例子中,两种情况下都会运行其中一个,这取决于链接器选择放弃内联冲突的任意规则。看起来像是“保留我看到的第一个”