c++ - 禁止跨编译单元包含不兼容的 header

标签 c++

这是一个理论问题:假设您有一个库并且它有两个标题。是否有可能使用 C++ 或预处理器宏或两者的组合来实现以下行为:

  1. 依赖项目可以在任意数量的编译单元中包含 Header 1 Header 2 而不会出错。
  2. 依赖项目不能包含两个 header ,即使它跨不同的编译单元也是如此。

对于第二种情况,我想要一些会导致某种错误(例如链接器错误)的结构。我不需要给出一个很好的错误消息,我只是想禁止在同一个依赖项目中包含两个不兼容的头文件。这可能吗?

示例:

Header1.h

// type definitions for foo, Version 1
...

Header2.h

// type definitions for foo, Version 2
...

场景 1:

// (linker) error, versions do not match
CompilationUnit1.cpp <-- Header1.h
CompilationUnit2.cpp <-- Header2.h

场景 2:

// ok, versions match
CompilationUnit1.cpp <-- Header2.h
CompilationUnit2.cpp <-- Header2.h

最佳答案

您正在使用 Visual C++,然后它可以完成(但请注意,它不可移植,除非您使用 /WX,否则您将收到警告而不是错误).使用 GCC(也许,我没试过)你可能会以某种方式使用 #pragma weak

因为每个编译单元都是单独编译的,所以您必须在链接器级别找到东西(导出函数,更改设置)。我发现最简单的方法是声明一个部分并在其上分配一个虚拟变量。如果此部分在您的 header 上声明为具有不同的属性,则链接器会提示。

您必须将此添加到 Header1.h:

#pragma section("mylib_priv_impl_section",read)
__declspec(allocate("mylib_priv_impl_section")) static int mylib_priv_impl_var = 0;

然后在Header2.h中:

#pragma section("mylib_priv_impl_section",read,write)
__declspec(allocate("mylib_priv_impl_section")) static int mylib_priv_impl_var = 0;

现在当你编译和链接时你会得到这个警告:

multiple 'mylib_priv_impl_section' sections found with different attributes (C0300040)

因为我们用不同的属性声明了相同的部分(read 在 Header1 和 read+write 在 Header2)。不幸的是,这只是一个警告(您可以使用部分名称来提供一些有用的诊断信息)并且要停止编译,您必须指定 /WX(不幸的是被 #pragma comment(linker, "/WX ")).

请注意,我们需要那个dummy 变量,否则我们声明的部分(如果未使用)将被简单地忽略。除了我们的虚拟变量外,其他什么都不会放在该部分(另请参见 Scope of __declspec allocations)。


请注意,如果预处理器宏可行,那么解决方案也类似于 Marco Giordano建议将工作顺利。如果您包含 Header1 但您设置要使用 Version2(反之亦然)而不是包含要包含的宏,我只是更改它抛出错误的工作方式。像这样的东西(在 Header1 中和 Header2 中的镜面反射):

#if MyLibVersion != 1
#error You are including version 1 headers, please set MyLibVersion accordingly.
#endif

关于c++ - 禁止跨编译单元包含不兼容的 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34924799/

相关文章:

java - 服务器端收到 UDP 错误数据

带有 fstream 或数据库的 C++

c++ - C++ 中的 tr1::array 删除所有元素

c++ - 如何保存 vector 迭代器的值?

c++ - 不使用宏来减少函数定义的原因

c++ - 将 vector 元素移动到 vector 的后面

c++ - 如何使用c++以编程方式从操作系统中的pid获取uid?

C++ 外部函数名称重叠

c++ - 共享 Lua 脚本的安全性

c++ - 包含函数的 C 宏