假设我们有以下代码:
typedef struct {
int f1;
int f2;
} t_str;
int f(t_str* p, t_str* q)
{
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
p[0].f1++;
q[0].f2++;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我们使用-O3选项编译它(我使用gcc-5.1.0)时,编译器获得以下汇编程序:
f:
.LFB0:
.cfi_startproc
movl 8(%esp), %edx
movl 4(%esp), %ecx
movl 4(%edx), %eax
addl $9, (%ecx)
addl $9, %eax
movl %eax, 4(%edx)
xorl %eax, %eax
ret
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
这意味着gcc决定访问p的字段f1并且访问q的字段f2永远不会别名.我想这来自于假设两个相同类型的对象从不重叠或它们是相同的.但我没有在标准中找到问题.
所以,请问,任何人都可以在标准中找到这个问题,或者另外一点为什么gcc限制了字段访问,或评论发生了什么?
UPD:
好吧,我也考虑了6.5节的第7段,但是对于我来说,对于所有对象都有明确形式的东西会更舒服:
6.5.16.1简单分配
3如果从另一个与第一个对象的存储方式重叠的对象中读取存储在对象中的值,则重叠应该是精确的,并且这两个对象应具有兼容类型的合格或不合格版本; 否则,行为未定义.
不幸的是,这条规则不能在这里使用.
现在看,如果对于上面的代码我做了以下功能:
void main()
{
char * c = …Run Code Online (Sandbox Code Playgroud)