c++ - 是否可以对所有翻译单元进行定义?
问题描述
可以跨所有翻译单元进行#define 或类似的预处理器定义吗?
标头实现对于非常小的库很有用,因为所有代码都可以包含和分布在具有以下结构的单个标头中:
// library.h
void libFunc(); // forward decl
#ifdef IMPLEMENT_LIBRARY
int libState;
volatile int libVolState; // library state exposed to external processes
void libFunc(){
// definition
}
#endif
然而,这种结构要求用户IMPLEMENT_LIBRARY
在标头仅包含在他们的一个翻译单元中之前进行定义,这意味着它不能放在用户的头文件中,并且对于不完全熟悉 C++ 编译的人来说可能有点混乱规则。
如果有一种方法可以IMPLEMENT_LIBRARY
跨所有 TU 进行定义,则可以使用以下命令自动完成
#ifndef IMPLEMENT_LIBRARY
#defineToAllUnits IMPLEMENT_LIBRARY
// library state
// definitions
#endif
是否存在这样的机制,或者当前的单头系统是否与它将获得的一样好?
解决方案
对于这个用例,您可能根本不应该使用宏定义。如果要在库用户的 TU 中定义函数,可以使用内联函数。内联函数可以在多个 TU 中定义(只要定义相同):
// library.h
inline void libFunc(){
// definition
}
另一种方法是单独编译库,并让库的用户与其链接,而不是在他们自己的 TU 中进行定义。
关于问题本身
可以跨所有翻译单元进行#define 或类似的预处理器定义吗?
可以在多个 TU 中 #define 预处理器宏:
// a.cpp
#define foo a
// b.cpp
#define foo b
如果您希望定义在定义它的所有 TU 中匹配,您可以将宏定义放入头文件中,并包括:
// h.hpp
#define foo h
// a.cpp
#include "h.hpp"
// b.cpp
#include "h.hpp"
不可能将一个 TU 中的定义“注入”到其他 TU 中,因此没有可能等效于“#defineToAllUnits”。通常可以从编译器调用中“注入”宏定义:gcc a.cpp b.cpp -Dfoo=h
. 但是,我认为这对您的用例没有用。
推荐阅读
- firebase - 颤振升级后,Firebase 电话身份验证无法构建
- javascript - Bootstrap CSS 仅适用于 PC 网络浏览器,不适用于移动浏览器
- go - Golang Pgx 池动态配置
- python - 如何抑制来自 Tensorflow 的所有签名警告?
- visual-studio - 创建 Vulkan 开发人员环境时 glfw.3lib 的许多链接器错误
- entity-framework-core - 运行时 EF EnsureCreatedAsync 上的“找不到方法”
- wordpress - 分析 - IBM Watson 助手
- c++ - 尝试使用 CodeBlocks 创建一个 Sales_item.h 类
- python - 在 tkinter / Canvas 中创建菜单
- php - Laravel 8 - 连接到 SQL 数据库成功,但无法查询