int可以作为unsigned int别名吗? [重复]

问题描述 投票:3回答:1

编译器生成代码,假设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中,如果eaxb引用同一个对象,则返回值(在a寄存器中)为10或12。在第二个重载中,ab不能引用同一个对象,因此返回值始终为10。

严格的别名规则由C ++标准[intro.object]/8的这一段表示:

[...]如果一个嵌套在另一个中,则两个具有重叠生命周期且不是位字段的对象a和b可以具有相同的地址,或者如果至少一个是零大小的基类子对象并且它们是不同的类型;否则,他们有不同的地址。

所以根据这个规则,int不能被unsigned int别名。

问题:

  1. 在C ++标准中,这个规则有一个例外,它允许intunsigned int进行别名处理吗?
  2. 如果没有,为什么所有编译器都假设这种可能性?
c++ language-lawyer strict-aliasing
1个回答
4
投票

C ++标准中的此规则是否有例外,它允许通过unsigned int对int进行别名?

是的,这是[basic.lval]/8

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:

  • 与对象的动态类型对应的有符号或无符号类型的类型,
  • 一种类型,是有符号或无符号类型,对应于对象动态类型的cv限定版本,
© www.soinside.com 2019 - 2024. All rights reserved.