使用 g++ 预处理器进行替换会导致链接错误
Substitution using g++ preprocessor makes link error
你们知道为什么下面的代码会让 g++ 出现链接错误吗?(不是编译错误(
我很好奇 g++ 在这里是如何工作的
目的的简要说明
- 主要用途 AAA类
- AAA 类使用 BBB 类(BBB 是一个库(
- 尝试使用预处理器在主函数中将类 BBB 替换为假类
文件结构
project
|-- src
| |-- main.cpp
| |-- aaa.h
| |-- aaa.cpp
|-- lib
|-- bbb.h
|-- bbb.cpp
源文件
- 主.cpp
#include <iostream>
#define BBB BBB_substitution
#include "../lib/bbb.h"
#undef BBB
class BBB {
public:
void print() {
std::cout << "Fake: hello world" << std::endl;
}
};
#include "aaa.h"
int main() {
AAA aaa;
aaa.print();
}
- aaa.h
#pragma once
#include "../lib/bbb.h"
class AAA {
public:
BBB bbb;
void print();
};
- aaa.cpp
#include "aaa.h"
void AAA::print() {
bbb.print();
}
- bbb.h
#pragma once
class BBB {
public:
void print();
};
- bbb.cpp
#include <iostream>
#include "bbb.h"
void BBB::print() {
std::cout << "Real: hello world" << std::endl;
}
代码中存在 ODR 冲突。该规则规定,类定义在每个翻译单元中需要具有相同的标记序列。即使一个名称不同,ODR 也会中断,并且行为未定义。
翻译单元main.cpp
编译如下:
class BBB {
public:
void print() {
std::cout << "Fake: hello world" << std::endl;
}
};
翻译单元bbb.cpp
和aaa.cpp
编译为:
class BBB {
public:
void print();
};
print()
之后的令牌在main.cpp
中{
,而在bbb.cpp
和aaa.cpp
print()
之后的下一个令牌是;
。只有这样就足以破坏 ODR 并且代码的行为未定义。
若要执行要执行的操作,请将代码与不同的BBB::print
实现链接:
c++ main.cpp aaa.cpp bbb.cpp -o normal_executable
c++ main.cpp aaa.cpp bbb_mock.cpp -o test_code_executable
其中bbb_mock.cpp
"模拟"/实现在bbb.h
中公开的接口。
相关文章:
- 静态数据成员的问题-修复链接错误会导致编译器错误
- Visual Studio mkl_link_tool.exe链接错误
- C++ 实现模板单例类时出现链接错误
- 使用类模板的方法链接错误
- MySQL C++连接器链接错误
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 运行 C++ 单元测试时LNK2005链接错误
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 链接错误,包括我创建的相同头文件 - C++
- 在Embarcadero C++ Builder中生成的DLL未解决的外部链接错误
- 使用标头保护的多个定义链接错误
- 链接错误:未定义对 stdscr 和 wgetch 的引用
- 使用 Vivek 的 Vcam / 捕获源过滤器构建/链接错误
- 升压program_options中的链接错误
- 使用 g++ 预处理器进行替换会导致链接错误
- 在调试配置中编译工作正常,但发布会给出链接错误
- 相邻矩阵设置链接错误
- 包含常量变量并包含在多个文件中的标头的链接错误
- C++链接错误,我理解但无法解决
- 是什么导致macOS Mojave上的GoogleTest链接错误