Joh*_*ing 11 c++ gcc compiler-options
我开发了一个跨平台的库,可以在套接字通信中合理使用类型.该库已经在许多项目中使用,其中一些我可能不知道.
错误地使用此库可能会导致危险的未定义行为.我想尽我所能确保正确使用这个库.
除了文档当然,在G ++下,我知道要做的最好的方法是使用-fstrict_aliasing和-Wstrict-aliasing选项.
GCC下是否有办法在源文件级别应用这些选项?
换句话说,我想写下面的内容:
#ifndef MY_FANCY_LIB_H
#define MY_FANCY_LIB_H
#pragma (something that pushes the current compiler options)
#pragma (something to set -fstrict_aliasing and -Wstrict-aliasing)
// ... my stuff ...
#pragma (something to pop the compiler options)
#endif
Run Code Online (Sandbox Code Playgroud)
有办法吗?
让我们从我认为错误的前提开始:
错误地使用此库可能会导致危险的未定义行为。我想尽我所能确保这个库得到正确使用。
如果您的库以破坏的方式进行类型双关,那么无论传递什么编译器标志,-fstrict-aliasing它都会根据 C++ 标准具有未定义的行为。当使用某些标志(特别是)编译时,该程序似乎可以在某些编译器上运行,这一事实并没有改变这一点。-fno-strict-aliasing
因此,最好的解决方案是按照 Florian 所说的那样:更改代码,使其符合 C++ 语言规范。除非你这样做,否则你永远如履薄冰。
“是的,是的,”你说,“但在那之前,我能做些什么来缓解这个问题呢?”
我建议包括一个运行时检查,在库初始化期间使用,以检测以导致其行为不当的方式编译的情况。例如:
// Given two pointers to the *same* address, return 1 if the compiler
// is behaving as if -fstrict-aliasing is specified, and 0 if not.
//
// Based on https://blog.regehr.org/archives/959 .
static int sae_helper(int *h, long *k)
{
// Write a 1.
*h = 1;
// Overwrite it with all zeroes using a pointer with a different type.
// With naive semantics, '*h' is now 0. But when -fstrict-aliasing is
// enabled, the compiler will think 'h' and 'k' point to different
// memory locations ...
*k = 0;
// ... and therefore will optimize this read as 1.
return *h;
}
int strict_aliasing_enabled()
{
long k = 0;
// Undefined behavior! But we're only doing this because other
// code in the library also has undefined behavior, and we want
// to predict how that code will behave.
return sae_helper((int*)&k, &k);
}
Run Code Online (Sandbox Code Playgroud)
(上面是 C 而不是 C++,只是为了方便在两种语言中使用。)
现在,在您的初始化例程中,调用strict_aliasing_enabled(),如果它返回 1,则立即退出,并显示一条错误消息,表明库编译不正确。这将有助于保护最终用户免受不当行为的影响,并提醒客户端程序的开发人员他们需要修复其构建。
我已经用 gcc-5.4.0 和 clang-8.0.1 测试了这段代码。当-O2被传递时,strict_aliasing_enabled()返回 1。当-O2 -fno-strict-aliasing被传递时,该函数返回 0。
但让我再次强调:我的代码有未定义的行为!无法(可能)保证它会起作用。符合标准的 C++ 编译器可以将其编译成返回 0、崩溃或引发全球热核战争的代码!-fno-strict-aliasing如果您需要它按预期运行,那么您可能已经在库中其他地方使用的代码也是如此。
| 归档时间: |
|
| 查看次数: |
3675 次 |
| 最近记录: |