【问题标题】:Type of an expression表达式的类型
【发布时间】:2013-03-27 14:56:39
【问题描述】:

考虑 C++ 程序的以下部分;打印到控制台的值以 cmets 形式给出。

{ // case 1
unsigned int x = 10; 
unsigned int y = 20; 
std::cout << "u/u x - y: " << x-y << std::endl; // 4294967286
}   

{ // case 2
int x = 10; 
int y = 20; 
std::cout << "s/s x - y: " << x-y << std::endl; // -10
}   

{ // case 3
unsigned int x = 10; 
int y = 20; 
std::cout << "u/s x - y: " << x-y << std::endl; // 4294967286
}   

{ // case 4
int x = 10; 
unsigned int y = 20; 
std::cout << "s/u x - y: " << x-y << std::endl; // 4294967286
}

我试图弄清楚 C++(使用 gcc 4.7.2 尝试过)如何从表达式中定义类型(更具体地说,它的符号性)。对于情况 1、3 和 4,通常的算术转换应将这两个值提升为无符号整数:

 10 = b00000000000000000000000000001010
 20 = b00000000000000000000000000010100

然后,它会做一个 2 的补码得到 -20 并添加它:

 10 = b00000000000000000000000000001010
-20 = b11111111111111111111111111101100
      b11111111111111111111111111110110

将其解释为 无符号 整数,您会得到 4294967286 -- 很好。

显然,对于案例 2,您会得到相同的计算/结果;但是,通常的算术转换应该导致两个操作数都被解释为带符号的 int,并且结果似乎也被解释为 signed 整数。

据此,我推断,如果操作数在通常的算术转换之后被签名,则结果是有符号的。否则,结果是无符号的。

所以,我的问题是:

  1. 我的推论正确吗?
  2. 标准在哪里定义了这个?我在 C 或 C++ 标准中找不到对此的任何引用。
  3. 其他操作呢?我怀疑+* 等会以同样的方式工作,但是移位和逻辑操作呢?

编辑: 这似乎与C++11 type of (signed + unsigned)? 有关,但我的问题的关键部分似乎从那里接受的答案中丢失:表达式的结果是否总是两个操作数的类型在通常的算术转换之后?

【问题讨论】:

标签: c++ c language-lawyer


【解决方案1】:

转换遵循整数转换等级原则。简而言之,整数操作数的处理方式如下。

首先,每个小于int 的操作数都转换为int(如果原始类型的所有值都适合),否则转换为unsigned int

之后,如果(可能转换的)操作数类型是:

  • 完全一样,没有发生转换。

  • 大小相同,无符号优先。

  • 大小不同,较小的转换为较大的。如果较大的是无符号的,较小的也将转换为无符号的。

这种转换将操作数转换为相同的类型,这也是结果的类型。

C++11 标准的[expr]§9 涵盖了它。它还与[conv][conv.rank] 密切相关。 [expr] 的子章节中各个运算符的描述中涵盖了具体适用于哪些运算符。

【讨论】:

  • 是的,但我的问题的重点是操作数的类型是否总是决定表达式的类型(例如,它依赖于运算符)。
  • @rainer 我已经扩展了答案。
  • @rainer 是的,操作数类型几乎总是决定结果的类型。例外:不考虑&lt;&lt;&gt;&gt;&lt;&lt;=&gt;&gt;=中的移位计数操作数的类型; ==, !=, &lt;, &gt;, &lt;=, &gt;=, &amp;&amp;|| 总是产生 bool (C++) 或 int (C)操作数类型。
  • 我刚刚尝试了这个,结果非常令人惊讶:cpp.sh/72ew。根据我对这个答案的理解,我预计第一个结果是 >= 5,因为 -1 被“转换”(无论这意味着什么)为无符号;我本来预计第二个结果是
【解决方案2】:

好吧,这很简单,我只是误读了标准...来自 C++ 11, §5 [expr] p9:

许多二元运算符需要算术或 枚举类型导致转换并产生类似的结果类型 方法。 目的是产生一个通用类型,这也是 结果。 这种模式称为通常的算术转换,...​​

【讨论】:

  • 很好地说明您指的是哪个标准和所述标准的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2011-05-19
  • 2015-07-13
  • 2019-06-02
相关资源
最近更新 更多