编译器生成代码假设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
返回值(在eax
寄存器)是 10 或 12 如果b
and a
引用同一个对象。在第二次过载时,a
and b
不能引用同一个对象,因此返回值始终为 10。
C++ 标准的这一段表达了严格的别名规则,[介绍对象]/8 http://eel.is/c++draft/intro.object#8:
[...]两个对象a and b如果一个非位字段嵌套在另一个中,或者如果至少一个是零大小的基类子对象并且它们具有不同类型,那么具有重叠生命周期的非位字段可能具有相同的地址;否则,它们具有不同的地址。
所以根据这个规则,int
不能使用别名unsigned int
.
问题:
C++ 标准中是否有此规则的例外,允许使用别名int
by unsigned int
?
如果不是,为什么所有编译器都假设这种可能性?