关于char和严格别名的通用指针

时间:2012-09-09 08:23:56

标签: c char strict-aliasing

我不知道为什么以下代码正常,没有gcc错误(-fstrict-aliasing -Wstrict-aliasing=1)。

#include <stdio.h>

int 
main(void) 
{
    char  n = 42;
    char *p = &n;
    int  *q = (int *)p;

    *q = 10;

    printf("%d|%d\n", *p, *q);

    return 0;
}

如果我遵循严格的别名规则:

  

n1570,§6.5表达式

     

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

     

- 与对象的有效类型兼容的类型,

     

- 与对象的有效类型兼容的类型的限定版本

     

- 对应于有效类型的有符号或无符号类型   对象,

     

- 对应于对象有效类型的限定版本的有符号或无符号类型,

     

- 聚合或联合类型,其成员中包含上述类型之一(包括递归地,子聚合或包含联合的成员),或

     

- 字符类型。

但是*q没有与*p兼容的类型,无论是合格版本,还是对应的有符号或无符号类型,都是字符类型。

那么,为什么允许这样做?

1 个答案:

答案 0 :(得分:3)

不允许。您发布的标准部分显示了您允许使用别名对象的类型。

编译代码的事实并不意味着它是正确的。您遇到的代码存在三个问题,导致程序显示未定义的行为。

首先,您指定了一个指向int指针的char指针。 标准没有强制执行它们的对齐和表示,因此结果指针无效。

int  *q = (int *)p;

然后您将char n对象解释为整数,违反严格别名。(请注意问题中标准的引用)。

*q;

最后你在char对象(int)的内存中写了一个char n,这会导致溢出,因为int的大小总是大于{{}的大小1}}。

char