代码之家  ›  专栏  ›  技术社区  ›  stoper

防止同一宏在多个转换单元中具有不同的定义

  •  2
  • stoper  · 技术社区  · 7 年前

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

    例如,应防止:

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

    库将提供标题-库。hpp-将包含在所有使用它的翻译单元中。我的想法是使用该标题作为创建滥用检查的位置。

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

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

    • 汇编
    • 链接
    • 运行时

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

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

    独立于平台的解决方案是最好的,但对于gcc/clang和msvc来说,独立完成这项工作的方法也很有用。

    宏定义将始终为整数。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Matthias    7 年前

    沿着这条路线做点什么怎么样:

    主要的cpp:

    int checkMyMacro#MY\u MACRO;

    a、 cpp和b.cpp:

    静态int*checkMyMacro=&选中MyMacro#MY\u MACRO;

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

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

        2
  •  -2
  •   Guillaume Racicot    7 年前

    如果您只想防止意外误用,那么以下内容可能就足够了:

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

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