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