gpt4 book ai didi

c++ - GCC pragma 在源文件中添加/删除编译器选项

转载 作者:可可西里 更新时间:2023-11-01 15:28:40 24 4
gpt4 key购买 nike

我开发了一个跨平台的库,它充分利用了 type-punning在套接字通信中。这个库已经在许多项目中使用,其中一些我可能不知道。

不正确地使用这个库会导致危险的未定义行为。我想尽我所能确保正确使用此库。

当然,除了文档,在 G++ 下,我知道最好的方法是使用 -fstrict_aliasing-Wstrict-aliasing 选项。

在 GCC 下有没有办法在源文件级别应用这些选项?

换句话说,我想写如下内容:

MyFancyLib.h

#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

有办法吗?

最佳答案

让我们从我认为是错误的前提开始:

Using this library incorrectly can result in dangerously Undefined Behavior. I would like to ensure to the best of my ability that this library is being used properly.

如果您的库以 -fstrict-aliasing 中断的方式进行类型双关,那么根据 C++ 标准,它具有未定义的行为无论传递什么编译器标志 .该程序在使用特定标志(特别是 -fno-strict-aliasing)编译时似乎适用于特定编译器这一事实并没有改变这一点。

因此,最好的解决办法是按照 Florian 所说:更改代码,使其符合 C++ 语言规范。在您这样做之前,您将永远如履薄冰。

“是的,是的”,你说,“但在那之前,我能做些什么来缓解这个问题?”

我建议包括 run-time check ,在库初始化期间使用,以检测以导致其行为异常的方式编译的情况。例如:

// 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);
}

(以上是 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、崩溃或启动 Global Thermonuclear War 的代码。 !如果您需要 -fno-strict-aliasing 以使其按预期运行,那么您可能已经在库中的其他地方使用的代码也是如此。

关于c++ - GCC pragma 在源文件中添加/删除编译器选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19431723/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com