C 中的严格别名 [英] strict aliasing in C

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

问题描述

关于类型双关的问题:为什么这段代码违反了严格的别名规则:

Question about type punning: why does this code break strict aliasing rules:

int main()
{
    int a = 1;
    short j;

    printf("%i
", j = *((short*)&a));
    return 0;
}

这不是:

int main()
{
    int a = 1;
    short j;
    int *p; 

    p=&a;
    printf("%i
", j = *((short*)p));
    return 0;
}

通过 gcc -fstrict-aliasing 构建.

谢谢!

推荐答案

它们都违反了严格的别名规则,我我要引用我的这里的答案,上面写着(强调我的未来):

They both violate the strict aliasing rule, I am going to quote my answer here which says (emphasis mine going forward):

代码违反了严格的别名规则通过不同类型的指针访问对象是非法的,尽管允许通过字符 * 访问.允许编译器假设不同类型的指针不指向相同的内存并进行相应的优化.

code violates the strict aliasing rules which makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly.

gcc-Wstrict-aliasing=n 这里 说:

此选项仅在 -fstrict-aliasing 处于活动状态时才处于活动状态.它警告可能会破坏编译器用于优化的严格别名规则的代码.更高的级别对应更高的准确度(更少的误报).更高的级别也对应更多的努力,类似于 -O 的工作方式.-Wstrict-aliasing 等价于 -Wstrict-aliasing=3.

This option is only active when -fstrict-aliasing is active. It warns about code that might break the strict aliasing rules that the compiler is using for optimization. Higher levels correspond to higher accuracy (fewer false positives). Higher levels also correspond to more effort, similar to the way -O works. -Wstrict-aliasing is equivalent to -Wstrict-aliasing=3.

并将每个级别描述如下:

and describes each level as follows:

  • 1 级:最具攻击性、快速、最不准确.可能有用的时候更高级别不会发出警告,但 -fstrict-aliasing 仍然会破坏代码,因为它的假阴性很少.然而,它有许多虚假积极的一面.对可能之间的所有指针转换发出警告不兼容的类型,即使从未取消引用.在前端运行仅.

  • Level 1: Most aggressive, quick, least accurate. Possibly useful when higher levels do not warn but -fstrict-aliasing still breaks the code, as it has very few false negatives. However, it has many false positives. Warns for all pointer conversions between possibly incompatible types, even if never dereferenced. Runs in the front end only.

第 2 级:积极、快速、不太精确.可能还有很多虚假阳性(虽然没有级别 1 多),并且很少有假阴性(但可能超过 1 级).与级别 1 不同,它仅在以下情况发出警告取一个地址.警告不完整的类型.跑在前面仅结束.

Level 2: Aggressive, quick, not too precise. May still have many false positives (not as many as level 1 though), and few false negatives (but possibly more than level 1). Unlike level 1, it only warns when an address is taken. Warns about incomplete types. Runs in the front end only.

级别 3(-Wstrict-aliasing 的默认值):应该有很少的 false阳性和很少的假阴性.比 1 级或 2 级略慢启用优化时.处理常见的双关语+取消引用前端模式:*(int*)&some_float. 如果优化是启用,它也在后端运行,在那里处理多个使用对流敏感的指向信息的语句案例.只警告当转换的指针被取消引用时.不警告不完整的类型.

Level 3 (default for -Wstrict-aliasing): Should have very few false positives and few false negatives. Slightly slower than levels 1 or 2 when optimization is enabled. Takes care of the common pun+dereference pattern in the front end: *(int*)&some_float. If optimization is enabled, it also runs in the back end, where it deals with multiple statement cases using flow-sensitive points-to information. Only warns when the converted pointer is dereferenced. Does not warn about incomplete types.

因此不能保证捕获所有实例,并且不同级别具有不同程度的准确度.

So it is not guaranteed to catch all instances and different levels have different degrees of accuracy.

通常可以通过联合使用类型双关语来实现您正在寻找的效果,我在上面的链接答案和gcc 明确支持.

Typically the effect you are looking for can be accomplished using type punning through a union, which I cover in my linked answer above and gcc explicitly supports.

这篇关于C 中的严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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