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

时间:2018-01-05 17:45:56

标签: 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 - 将包含在使用它的所有翻译单元中。我的想法是使用该标题作为创建误用检查的地方。

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

在下列期间,优选地按优先顺序检测误用:

  • 汇编
  • 运行时

由于C / C ++编译器的工作方式,编译过程中可能无法实现。但也许至少在链接期间?

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

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

宏定义永远是一个整数。

2 个答案:

答案 0 :(得分:1)

这些方面的内容如何:

main.cpp:

int checkMyMacro#MY_MACRO;

a.cpp和b.cpp:

static int * checkMyMacro =& checkMyMacro#MY_MACRO;

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

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

答案 1 :(得分:-1)

如果您只是希望防止意外滥用,可能就足够了以下内容:

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

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