如果它们具有相同的对齐方式,则将指针指向float指针是否合法?

时间:2015-03-09 16:19:26

标签: c pointers undefined-behavior type-punning

我们说intfloat都是4字节对齐的。根据ISO C99 6.3.2.3第7页:

  

指向对象或不完整类型的指针可以转换为   指向不同对象或不完整类型的指针。如果结果   指针未正确对齐指向类型的行为   未定义。

根据这一点,以下代码不应该调用UB:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i = 7;
    float *f = (float *) &i;
    exit(0);
}

我注意到GCC并不总是擅长捕获严格的别名规则违规尝试,但是这里可以正确警告解除引用* f 中断将违反严格别名规则什么是非法的6.5 p 。 7:

  

对象的存储值只能通过左值表达式访问   具有以下类型之一:

     
      
  • 与对象的有效类型兼容的类型
  •   
  • 与有效类型兼容的类型的限定版本     对象,
  •   
  • 一种类型,是与之对应的有符号或无符号类型     有效的对象类型,
  •   
  • 与a对应的有符号或无符号类型的类型     对象的有效类型的限定版本,
  •   
  • 包含上述之一的聚合或联合类型     其成员之间的类型(包括,递归地,成员     subaggregate或contains union),或
  •   
  • 字符类型。
  •   
$ gcc  -Wall -fstrict-aliasing -Wstrict-aliasing=2 so1.c -Wcast-align
so1.c: In function ‘main’:
so1.c:7:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
so1.c:7:9: warning: unused variable ‘f’ [-Wunused-variable]

这是否意味着只有当* f被解除引用并且它在当前形状下100%正确时,此代码才可以调用UB?

修改

还有一件事 - 如果float与int的大小不同,那么这个演员也是合法的,但两种类型的对齐方式仍然相同吗?我想是的,因为这是C标准所说的,但我不明白为什么对齐在这里是最重要的而不是尺寸。为什么在转换指针时以及仅在解除引用时对齐很重要?

0 个答案:

没有答案