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

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

 #include  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兼容的类型,无论是合格版本,还是对应的有符号或无符号类型,都是字符类型。

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

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

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

首先,您指定了一个指向int指针的char指针。 Standard不会强制执行它们的对齐和表示,因此生成的指针无效。

 int *q = (int *)p; 

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

 *q; 

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

 *q = 10;