如何最好地防止库(源)和应用程序(头)编译之间的(编译器)标志不匹配
How to best safeguard against mismatch of (compiler) flags between library (source) and application (header) compilations?
在实现头文件中给定的某些接口时,如何最好地防止库实现的编译与头文件之间的危险不匹配?
详细信息:库接口由头文件(例如foo.h
)提供,并由某些源文件(例如,foo.cc
)实现。后者被编译以创建库,例如libfoo.so
,而前者#include<>
由一个应用程序执行,该应用程序与libfoo.so
链接。
现在,假设在foo.h
中
// foo.h
namespace foo {
class bar
{
#ifdef SomeOption
std::int32_t x[2];
#else
std::int64_t x[2];
#endif
bar const*ptr;
/* ... */
};
}
则ptr
的偏移量是8或16字节,这取决于SomeOption
(并且sizeof(bar)
也不同)。现在,如果使用与应用程序不同的SomeOption
值编译库,那么显然会出现严重的问题(对于不知情的人来说很难调试)。
解决方案所以,我想出了以下想法
// foo.h
namespace foo {
enum { hasSomeOption = 1 };
int options_flags()
{
return 0
#ifdef SomeOption
| hasSomeOption
#endif
;
}
class bar
{
/* ... as before */
bar(some_args, int);
public:
bar(some_args) : bar(some_args, options_flags()) {} // what's option_flags()?
/* ... */
};
}
和
// foo.cc
namespace {
const int src_flags = options_flags(); // flags used for compiling library source
}
namespace foo {
bar::bar(some_args, int app_flags)
{
assert(app_flags == src_flags);
/* ... */
}
}
具有CCD_ 11将捕获任何不一致的想法。然而,这不起作用:编译器似乎优化了我的想法,断言永远不会触发,即使SomeOption
不同于库和应用程序编译。
问题对于这类问题,有推荐的最佳方法吗?
我希望有更好的方法,但您可以随时根据选项更改类或命名空间名称,这样,如果有人使用了错误的编译器选项,就找不到类。
更改名称空间的名称似乎更好——使用调试器时不会引起太多混乱。类似这样的东西:
#ifdef SomeOption
#define foo foo_32bit
#else
#define foo foo_64bit
#endif
namespace foo
{
....
}
我想它会起作用,但它确实很难看。
相关文章:
- 热键/按钮,根据需要进行编译,但不运行(在F5和Ctrl+Shift+B之间)
- MSVC 2010 编译应用程序和 MSVC 2019 编译应用程序之间的行为差异
- C++ 编译时在两个变量之间交替
- 在VS2017中,我们如何在项目成员之间共享编译设置
- 为什么 GCC 和 clang 之间编译的 c++17 lambda 存在差异?
- 如果我在下面的代码中使用 list 而不是 vector,为什么在我尝试在迭代器之间执行减法的行中编译失败?
- Visual Studio 2015:在远程编译(在Raspberry上)和本地编译(在Windows上)之间切换
- 使用运行时参数与编译时参数在类之间共享代码
- C++编译错误(有符号和无符号整数表达式之间的比较)
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突
- 根据编译时条件在类型之间选择类型的惯用方法
- 结构成员的地址作为编译时间常数之间的差异
- 我的编译行和我的生成文件之间的区别可能导致错误
- 预编译的头文件和预编译的二进制文件之间的区别是什么
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 编译单元之间共享的全局常量对象
- 编译一个相当简单的c++11程序时,gcc和clang之间的结果不同
- 使用编译代码和 PHP 加速器来提高性能之间的差异
- 编译宏以测试uint64_t和无符号长整型之间的差异
- 2个c源文件之间的函数指针操作导致编译时错误