>编译器生成代码,假设int
可以被unsigned int
别名。以下代码:
int f(int& a, unsigned int& b){
a=10;
b=12;
return a;
}
int f(int& a, double& b){
a=10;
b=12;
return a;
}
使用 Clang5 生成以下程序集(GCC 或 ICC 生成类似的代码):
f(int&, unsigned int&): # @f(int&, unsigned int&)
mov dword ptr [rdi], 10
mov dword ptr [rsi], 12
mov eax, dword ptr [rdi] #return value must be loaded since rdi might equal rsi
ret
f(int&, double&): # @f(int&, double&)
mov dword ptr [rdi], 10
movabs rax, 4622945017495814144
mov qword ptr [rsi], rax
mov eax, 10 #return value is a direct value.
ret
在上面的示例中,在第一个重载f
如果b
和a
引用同一对象,则返回值(在寄存器eax
中)为 10 或 12。在第二个重载中,a
和b
不能引用同一个对象,因此返回值始终为 10。
严格的混叠规则由C++标准的这一段[intro.object]/8表示:
[...]如果两个对象a和b具有重叠的生存期(不是位字段)可能具有相同的地址,或者如果至少有一个对象是大小为零的基类子对象并且它们属于不同的类型;否则,它们具有不同的地址。
所以根据这个规则,int
不能被unsigned int
混叠。
问题:
C++标准中是否有此规则的例外情况,允许按
unsigned int
混叠int
?如果不是,为什么所有编译器都假设这种可能性?
在C++标准中,此规则是否有例外,允许无符号 int 混叠 int?
是的,它是 [basic.lval]/8:
如果程序尝试通过以下方式访问对象的存储值 不是以下类型之一的 glvalue 行为是 定义:
- 一种类型,该类型是对应于对象的动态类型的有符号或无符号类型,
一种类型,- 该类型是与对象的动态类型的 CV 限定版本相对应的有符号或无符号类型,