在clang中,您如何使用每个函数的优化属性?

mpo*_*llo 11 c clang compiler-optimization

我正在尝试编译一个没有使用优化的特定函数,clang以防止某些与安全相关的调用memset()被优化掉.

根据可在此处找到的文档,存在optnone允许此属性的属性.此外,这里可以找到一个例子.

不幸的是,(至少在clangOS X 10.9.5 的下面版本中),这会导致编译器警告,如本示例所示:

$ clang --version
Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

$ cat optnone.c
#include <string.h>

__attribute__((optnone)) void*
always_memset(void *b, int c, size_t len)
{
    return memset(b, c, len);
}

$ clang -Wall -O3 -c -o optnone.o optnone.c
optnone.c:3:16: warning: unknown attribute 'optnone' ignored [-Wattributes]
__attribute__((optnone)) void*
               ^
1 warning generated.
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用#pragma clang optimize off,但这引起了unknown pragma ignored警告.

有谁知道为什么这不起作用?我是否错过了使用此功能的先决条件?(我也尝试使用各种不同的-std=参数,包括c11,gnu11,c99,和gnu99,但没有改变的行为.)

Evg*_*yZh 6

正如clang文档所说,

Clang支持GCC的gnu属性命名空间.__attribute__((foo))语法接受的所有GCC属性也被接受为[[gnu::foo]].这仅扩展到GCC指定的属性(请参阅GCC函数属性列表,GCC变量属性和GCC类型属性).与GCC实现一样,这些属性必须与声明中的declarator-id相关,这意味着它们必须在声明的开头或声明名称之后立即进行.

尝试

void* always_memset(void *b, int c, size_t len) [[gnu::optimize(0)]]
Run Code Online (Sandbox Code Playgroud)

要么

void* always_memset(void *b, int c, size_t len) __attribute__ ((optimize("0")));
Run Code Online (Sandbox Code Playgroud)

  • 您应该尝试`__attribute __((optnone))`而不是在我的机器上定义`optimize("0")` (14认同)

Pau*_*ice 6

正如@dulacc 在他的评论中所提倡的,__attribute__ ((optnone))在 Mac 的 High Sierra 上使用 clang 9.0.0。

  • __attribute__((optnone)) 适用于 Windows,但结果相当低效,因为它关闭了所有优化。我真的很怀念 gcc 对优化的更详细的控制,例如 __attribute__((optimize("-fno-unsafe-math-optimizations"))) (3认同)