【问题标题】:Constant integer promotion rules?常量整数提升规则?
【发布时间】:2014-09-05 09:22:17
【问题描述】:

为了提供一点背景知识(与后面的问题无关),在 C++11 中我注意到了一个缩小范围的问题:

int foo[] = { 0xFFFFFFFF };

因为0xFFFFFFFFunsigned int,所以编译失败(缩小转换)。但是,我见过0xFF 签名的情况。

我查看了整数提升规则,但这主要是在左值而不是右值/常量的上下文中。编译器如何确定常量的类型(没有文字后缀)?是否有显示此规则的文档或漂亮的小表格/“备忘单”?我什至不确定这叫什么,否则我会尝试自己在 C++11 标准中找到它。

提前致谢。

【问题讨论】:

  • 它是签名优先级所需的最窄类型,至少为int
  • 我在回答中添加了一些额外的细节,您可能会觉得它们有用/有趣。

标签: c++ c++11


【解决方案1】:

标准中有一个表格,转载于cppreference.com:http://en.cppreference.com/w/cpp/language/integer_literal

特别是,没有后缀的十六进制或八进制整数文字被认为具有以下列表中可以表示其值的第一种类型:

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

0xFFFFFFFF 对于int 来说太大了,如果int 是 32 位长,则选择 unsigned int。但是0xFF 很适合int,所以int 是。

【讨论】:

  • 所以可以肯定地说它着眼于整数范围,而不是具体的位深度。如果是这样的话,这有助于使事情变得一目了然。
  • @RobertDailey 没错,是的,它不直接取决于位数,尽管显然它是间接的。
【解决方案2】:

在 C 中称为 整数常量 在 C++ 中称为 整数文字。用于确定 整数文字 类型的规则包含在 draft C++ standard 部分 2.14.2 整数文字6 中:

整数字面量的类型是对应列表的第一个 在表6中可以表示其值。

对于没有后缀的八进制或十六进制常量,表格的顺序如下:

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

所以0xFF 可以表示为一个int,而第一个可以表示0xFFFFFFFF 的类型是unsigned int

十进制常量的顺序如下:

int
long int
long long int

我们可以看到十六进制和八进制文字的行为不同,我们可以看到that C99 has the same table Rationale for International Standard—Programming Languages—C 对此表示如下:

与十进制常量不同,八进制和十六进制常量太大而不能 如果在该类型的范围内,be int 将被键入为 unsigned int,因为 它们更有可能代表位模式或掩码,它们是 通常最好将其视为无符号数,而不是“实数”。

cppreference integer literal section 还在 文字的类型 小节中引用了表 6

【讨论】:

  • +1 用于引用标准并告诉我这个概念的名称。
  • 基本上,如果你想使用有符号整数,你应该使用int foo[] = {-1};
【解决方案3】:

0xFF 永远不会是负数。这是写255 的另一种方式。 (它的类型为int)。

0xFFFFFFFF 是一个很大的正数。 [lex.icon] 下有一个表格,它指定了整数常量的类型。对于没有后缀的十六进制常量,它是以下列表中第一个可以容纳大正数的类型:intunsigned intlong intunsigned long intlong long intunsigned long long int。实现可能会在此列表中添加自定义类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    相关资源
    最近更新 更多