c++ - 防止同一个宏在多个翻译单元中有不同的定义

标签 c++ interface c-preprocessor conditional-compilation translation-unit

我正在创建一个库,每个使用它的生成的二进制文件(.exe、.so、.dll)都需要不同的命令行定义的宏(-D 选项)。 我想确保将成为二进制结果一部分的每个翻译单元都使用相同的宏定义进行编译。这是为了例如防止意外的 ODR 违规和其他意外行为。

例如,应该避免这种情况:

g++ -DMY_MACRO=5 a.cpp
g++ -DMY_MACRO=7 b.cpp
ld a.o b.o -o result

库将提供 header - library.hpp - 将包含在所有使用它的翻译单元中。我的想法是将该 header 用作创建滥用检查的地方。

问题是,最好的方法是什么?

最好按优先顺序在以下期间检测到滥用:

  • 编译
  • 链接
  • 运行时

由于 C/C++ 编译器的工作方式,这在编译期间可能是不可能的。但也许至少在链接期间?

我想避免使用外部工具/脚本。我知道可以编写一个脚本遍历所有目标文件并检查是否所有文件都使用相同的值。但也许有一种对构建系统干扰较小的方法,只需重用 C++ 链接器或编译器的工作方式。

独立于平台的解决方案是最好的,但独立于 gcc/clang 和 msvc 的方法也很有用。

宏定义永远是一个整数。

最佳答案

按照这些思路怎么样:

主要.cpp:

int checkMyMacro#MY_MACRO;

a.cpp 和 b.cpp:

static int *checkMyMacro = &checkMyMacro#MY_MACRO;

导致链接器在误用时出现 Unresolved external 错误。

您可以将第二部分插入到定义该宏的 header 中。

关于c++ - 防止同一个宏在多个翻译单元中有不同的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48118722/

相关文章:

c# - 从 winforms 基类显式调用接口(interface)方法

c++ - C++ 宏中的函数式编程风格 : Is this documented anywhere?

c - 在 GNU C 宏 envSet(name) 中,(void) ""name 是什么意思?

c++ - 我们可以编写一个不使用 C++ 预处理器的可移植包含防护吗?

c++ - 是否可以在同一进程中拥有多个 ORB 对象?

c++ - C++中比较语句的含义

具有聚合初始化的 C++ 常量匿名实例

java - 有没有可用的软件或库可以用 C、C++、Java 或 Ruby 绘制 3 维螺钉?

php - Eclipse PDT 自动实现接口(interface)方法

go - fmt.Println() 时 golang 编译器会做什么