gcc C / C ++假定没有指针别名 [英] gcc C/C++ assume no pointer aliasing

查看:185
本文介绍了gcc C / C ++假定没有指针别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

显然,使用 restrict __ restrict __ 关键字允许根据具体情况指示给定内存元素没有指针别名。



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

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

解决方案

GCC可以选择 -fstrict-aliasing ,它可以在全局范围内启用别名优化,并期望 you 确保没有任何内容被非法混淆。对于 -O2 -O3 我相信启用了此优化。


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

  float f; 
int * p = reinterpret_cast< int *>(& f); // uh-oh
* p = 0x3FF00000; //打破严格别名

这个规则的关键例外是您可以通过指向 char 的指针。 (这是通过IO操作进行序列化所必需的。)



别名规则不能帮助编译器知道相同类型的指针是否相互混淆。考虑这个:

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

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


Having recently read that the main reason why fortran is faster than c/c++ in numerical computations is because there is no pointer aliasing.

Apparently, using restrict or __restrict__ keywords allows on a case by case basis to indicate the absence of pointer aliasing for a given memory element.

The icc compiler apparently has an option -fno-alias which allows one to globally assume that no aliasing is present. On gcc there is -fno-strict-aliasing, which applies only to a subset of all the aliasing situations.

Is there an option present in gcc, or are there some cases where no aliasing is assumed, when using certain optimization flags?

解决方案

GCC has the option -fstrict-aliasing which enables aliasing optimizations globally and expects you to ensure that nothing gets illegally aliased. This optimization is enabled for -O2 and -O3 I believe.

C++ has well defined aliasing rules, though, and standard-compliant code will not conflict with strict aliasing. In particular this means you're not allowed to access one variable through a pointer to a different type:

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

The crucial exception to this rule is that you can always access any variable through a pointer to char. (This is necessary for serializing through IO operations.)

The aliasing rules do not help the compiler to know whether any pointers of the same type alias each other. Consider this:

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

Here the compiler cannot know whether c points to different memory than a or b and has to be careful. I think this is where restrict makes a difference, essentially by promising that float * restrict c means that nobody aliases c.

这篇关于gcc C / C ++假定没有指针别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆