简体   繁体   English

C中的严格别名

[英]strict aliasing in C

Question about type punning: why does this code break strict aliasing rules: 关于类型双关语的问题:为什么这段代码会破坏严格的别名规则:

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

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

and this is not: 这不是:

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

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

Build by gcc -fstrict-aliasing . 通过gcc -fstrict-aliasing构建。

Thank you! 谢谢!

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. 代码违反了严格的别名规则 ,这使得通过不同类型的指针访问对象是非法的 ,尽管允许通过char *进行访问。 The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly. 允许编译器假设不同类型的指针不指向相同的存储器并相应地进行优化。

gcc is a little more detailed in the documetation of -Wstrict-aliasing=n here which says: gcc是在小的documetation更详细-Wstrict-aliasing=n 这里它说:

This option is only active when -fstrict-aliasing is active. 此选项仅在-fstrict-aliasing处于活动状态时处于活动状态。 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. 更高的级别也相应于更多的努力,类似于-O的工作方式。 -Wstrict-aliasing is equivalent to -Wstrict-aliasing=3. -Wstrict-aliasing相当于-Wstrict-aliasing = 3。

and describes each level as follows: 并描述每个级别如下:

  • Level 1: Most aggressive, quick, least accurate. 1级:最具攻击性,快速,最不准确。 Possibly useful when higher levels do not warn but -fstrict-aliasing still breaks the code, as it has very few false negatives. 当更高级别没有警告但-fstrict-aliasing仍然会破坏代码时可能很有用,因为它几乎没有错误的否定。 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. 仅在前端运行。

  • Level 2: Aggressive, quick, not too precise. 等级2:积极,快速,不太精确。 May still have many false positives (not as many as level 1 though), and few false negatives (but possibly more than level 1). 可能仍有许多误报(尽管不是1级),也没有假阴性(但可能超过1级)。 Unlike level 1, it only warns when an address is taken. 与级别1不同,它仅在发出地址时发出警告。 Warns about incomplete types. 警告不完整的类型。 Runs in the front end only. 仅在前端运行。

  • Level 3 (default for -Wstrict-aliasing): Should have very few false positives and few false negatives. 级别3(-Wstrict-aliasing的默认值):应该具有非常少的误报和很少的误报。 Slightly slower than levels 1 or 2 when optimization is enabled. 启用优化后,比级别1或2略慢。 Takes care of the common pun+dereference pattern in the front end: *(int*)&some_float . 在前端处理常见的pun + dereference模式: *(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. 因此不能保证捕获所有实例,不同级别具有不同程度的准确性。

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 . 通常,您正在寻找的效果可以通过联合使用类型惩罚来完成,我在上面的链接答案中介绍了gcc明确支持

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM