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

Prevent same macro having different definitions in multiple translation units

我正在创建一个库,每个使用它的生成的二进制文件(.exe、.so、.dll)需要不同的 command-line 定义的宏(-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++ 编译器的工作方式,在编译期间可能无法实现。但也许至少在链接期间?

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

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

宏定义永远是整数。

如果您只是想防止意外误用,像下面这样的东西可能就足够了:

#if defined(MY_MACRO) && MY_MACRO_MIN > MY_MACRO || MY_MACRO_MAX < MY_MACRO
#error MY_MACRO is out of range
#endif

在您描述的情况下,在 运行 时间之前的任何时候防止恶意滥用基本上是不可能的。

按照这些思路怎么样:

main.cpp:

int checkMyMacro#MY_MACRO;

a.cpp 和 b.cpp:

static int *checkMyMacro = &checkMyMacro#MY_MACRO;

导致链接器在误用时出现未解决的外部错误。

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