这个问题在这里已有答案:
编译器生成代码,假设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;
}
使用Clang 5生成以下程序集(类似的代码由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
和b
引用同一个对象,则返回值(在a
寄存器中)为10或12。在第二个重载中,a
和b
不能引用同一个对象,因此返回值始终为10。
严格的别名规则由C ++标准[intro.object]/8的这一段表示:
[...]如果一个嵌套在另一个中,则两个具有重叠生命周期且不是位字段的对象a和b可以具有相同的地址,或者如果至少一个是零大小的基类子对象并且它们是不同的类型;否则,他们有不同的地址。
所以根据这个规则,int
不能被unsigned int
别名。
问题:
int
对unsigned int
进行别名处理吗?C ++标准中的此规则是否有例外,它允许通过unsigned int对int进行别名?
是的,这是[basic.lval]/8:
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- 与对象的动态类型对应的有符号或无符号类型的类型,
- 一种类型,是有符号或无符号类型,对应于对象动态类型的cv限定版本,