为什么对char应用位NOT会产生int

  • 本文关键字:NOT int 应用 char c++
  • 更新时间 :
  • 英文 :


在我的笔记本电脑上,运行以下代码:

#include <iostream>
using namespace std;
int main()
{
    char a;
    cout << sizeof(~a) << endl;
}

打印CCD_ 1。

我原以为~a的结果是char,但显然,它是int

为什么?

~是一个算术运算符(按位NOT),a正从signed char升级为int(在许多实现中也是sizeof(int) == 4)。有关解释,请参见下文:

http://en.cppreference.com/w/cpp/language/implicit_conversion#integral_promotion

小积分类型(如char)的Prvalue可以转换为较大积分类型(如int)的pr值。特别地,算术运算符不接受小于int的类型作为在左值到右值的转换(如果适用)。此转换始终保留价值。

标准规定(§[expr.primary]/10):

~的操作数应具有整型或非整型枚举类型;结果是一个操作数的补码。进行整体促销。结果的类型是提升操作数的类型。

"整体促销"是指(§[conv.prom]/1):

如果46可以表示源类型的所有值,则除了整数转换秩(4.13)小于int的秩的boolchar16_tchar32_twchar_t之外的整数类型的prvalue可以被转换为int类型的prvalue;否则,可以将源prvalue转换为类型为unsigned int的prvalue。

在您的案例中,a的类型为char,它的转换秩小于int1的秩,因此它被提升为intunsigned int,这两个级别的大小相同(在您的实现中显然是4)。

至于为什么要这样做:我认为这在很大程度上简化了语言定义和编译器。它不必为几乎每种类型单独生成代码,而是尽最大努力将所有内容分解为少数类型,并且大多数代码只为这些类型生成。现在情况已经不是这样了(现在我们有多个大于int的类型),但在C年轻的时候,整数类型是:charshortint(以及这些类型的无符号版本),所以所有其他类型都升级为int,所有操作任何内容的代码都是用int s完成的。

请注意,这也适用于函数调用等:在C的早期版本中,没有函数原型,因此任何类型为charshort的参数在传递给函数之前都被提升为int

浮点类型也遵循同样的基本思想:在大多数情况下(包括将它们传递给函数),float s被提升为double,所有实际处理都在double s上完成(之后,如果需要,可以转换回float


  1. 如果你真的也想要报价(§[conv.rank]:

1.3如果int可以表示源类型的所有值,则可以将整数转换秩(4.13)小于int的秩的除bool、char16_t、char32_t或wchar_t之外的整数类型的prvalue转换为int类型的prvalue;否则,源prvalue可以转换为unsigned int类型的prvalue。
[…]
1.6字符的秩应等于有符号字符和无符号字符的秩。

相关内容

最新更新