可以将一个int别名为一个无符号int吗? [英] Can an int be aliased as an unsigned int?

查看:68
本文介绍了可以将一个int别名为一个无符号int吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译器会生成代码,假定 int 可以由 unsigned int 别名.以下代码:

Compiler generates code assuming that an int can be aliased by an unsigned int. The folowing code:

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生成):

generates the folowing assembly, using Clang5 (similar code is produced by GCC or 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 指的是同一对象.在第二次重载中, a b 无法引用同一对象,因此返回值始终为10.

In the example above, in the first overload f the return value (in eax register) is either 10 or 12 if b and a refer to the same object. In the second overload, a and b cannot refer to the same object so the return value is always 10.

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

The strict aliasing rule is expressed by this paragraph of the C++ standard, [intro.object]/8:

[...]如果两个对象 a b 嵌套在另一个对象中,则它们的寿命互为非位字段,它们可能具有相同的地址,或者如果至少一个是大小为零的基类子对象,并且它们是不同的类型;否则,它们有不同的地址.

[...] Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.

因此,根据此规则, int 不能由 unsigned int 别名.

So according to this rule, an int cannot be aliased by an unsigned int.

问题:

  1. 在C ++标准中是否存在此规则的例外,该例外允许通过 unsigned int 别名 int ?

如果不是,为什么所有编译器都采用这种可能性?

If not, why all compilers assume this possibility?

推荐答案

在C ++标准中是否存在此规则的例外,该例外允许以unsigned int别名int?

Is there an exception to this rule in the C++ standard that would allow aliasing of int by unsigned int?

是的,它是 [basic.lval]/8 :

如果程序尝试通过以下方式访问对象的存储值除以下类型之一以外的glvalue的行为是未定义:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • 一种类型,它是与对象的动态类型相对应的有符号或无符号类型,
  • 一种类型,它是与对象的动态类型的cv限定版本相对应的有符号或无符号类型,

这篇关于可以将一个int别名为一个无符号int吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆