10

最近读到 fortran 在数值计算中比 c/c++ 快的主要原因是因为没有指针别名。

显然,使用restrictor__restrict__关键字允许根据具体情况来指示给定内存元素不存在指针别名。

icc 编译器显然有一个选项-fno-alias,它允许全局假设不存在别名。在 gcc 上有-fno-strict-aliasing,它仅适用于所有别名情况的子集。

在使用某些优化标志时,gcc 中是否存在选项,或者是否存在不假定别名的情况?

4

1 回答 1

17

GCC 具有-fstrict-aliasing启用全局别名优化的选项,并希望确保没有任何东西被非法别名。我相信这种优化是启用的-O2-O3

不过,C++ 有明确定义的别名规则,并且符合标准的代码不会与严格的别名冲突。特别是这意味着您不允许通过指向不同类型的指针访问一个变量:

float f;
int * p = reinterpret_cast<int*>(&f);  // uh-oh
*p = 0x3FF00000;                       // breaks strict aliasing

此规则的关键例外是您始终可以通过指向char. (这对于通过 IO 操作进行序列化是必需的。)

别名规则不能帮助编译器知道任何相同类型的指针是否相互别名。考虑一下:

void add(float * a, float * b, float * c) { *c = *a + *b; }

这里编译器无法知道是否c指向不同的内存而不是aorb并且必须小心。我认为这是有所作为的地方restrict,本质上是通过承诺这float * restrict c意味着没有人别名c

于 2011-09-04T10:32:40.930 回答