C++ 在C表达式中字符是否自动升级?

C++ 在C表达式中字符是否自动升级?,c++,c,char,int,integer-promotion,C++,C,Char,Int,Integer Promotion,我向我的一位同事发表了一项声明,内容是: “在C表达式中,字符会自动升级为整数,这对性能很好,因为CPU以其自然字长工作得最快 我相信,由于char的排名,char的促销行为在标准的某个地方有所规定 这是我得到的回应: “默认情况下,字符不会升级为整数。寄存器大小 是32位,但行中的多个字节值可以打包到 单寄存器作为编译器实现。这并不总是如此 预测性的。唯一可以验证自动升级的时间是 当类型没有包装在调用堆栈中时,它将被传递到调用堆栈中 结构,因为C标准在 调用堆栈内存。大量的CPU架构已经优化

我向我的一位同事发表了一项声明,内容是:

“在C表达式中,字符会自动升级为整数,这对性能很好,因为CPU以其自然字长工作得最快

我相信,由于char的排名,char的促销行为在标准的某个地方有所规定

这是我得到的回应:

“默认情况下,字符不会升级为整数。寄存器大小 是32位,但行中的多个字节值可以打包到 单寄存器作为编译器实现。这并不总是如此 预测性的。唯一可以验证自动升级的时间是 当类型没有包装在调用堆栈中时,它将被传递到调用堆栈中 结构,因为C标准在 调用堆栈内存。大量的CPU架构已经优化 程序集调用非32位值,因此无法进行任何假设 关于本例中的CPU或编译器。”


我不确定谁是对的,也不确定该相信什么。事实是什么?

C不需要堆栈或指定任何关于32位寄存器的内容

integer促销的基本原理之一是:

执行整数升级是为了避免中间值溢出导致的算术错误。例如:


请注意,并不是所有运算符都会使其参数成为常用算术转换的主题,例如,赋值运算符或强制转换运算符没有整数提升。

是的,有多个
char
s的表达式,如加法等。(但不是逗号运算符等),以及其他一些事情,都是在提升值上完成的(提升为
int
)。参见第4.5节

关于你同事的陈述,有很多错误的地方:

  • “注册表”(寄存器)大小通常不是32位,根本不是

  • 如果一个字节有8位,那么一个32位的寄存器当然可以容纳多个字节,
    但这并不相关,编译器也不是它成为可能的原因

  • 这是“预测”吗

  • 关于标准和32位的位是完全错误的

  • 整数提升与
    struct

  • 在标准中,没有“堆栈”。该概念
    在现实中使用堆栈的属性并不是强制性的(正如其他人所说)

  • 他说所有东西都需要32位,但作为CPU
    也可以加工其他尺寸,没有什么可以确定的?现在怎么办

在C表达式中,字符会自动升级为整数

是的,它们是。C99第6.3.1.8节,常用算术转换

许多期望算术类型的操作数的运算符会导致转换并产生结果 类型。目的是确定操作数的通用实数类型 和结果。对于指定的操作数,将转换每个操作数,而不更改类型 域,指向其对应实类型为公共实类型的类型。除非 否则,公共实数类型也是 结果,其类型域是操作数的类型域(如果操作数相同), 这种模式称为通常的算术转换:

  • 首先,如果其中一个操作数的对应实数类型为长双精度,则另一个操作数 操作数在不改变类型域的情况下被转换为相应实型为长双精度的类型
  • 否则,如果任一操作数的对应实数类型为双精度,则另一个操作数 操作数在不更改域类型的情况下转换为 对应的实数类型是double
  • 否则,如果其中一个操作数的对应实数类型为float,则另一个操作数 操作数在不更改域类型的情况下转换为 相应的实数类型是float.62)
  • 否则,对两个操作数执行整数提升 以下规则应用于提升的操作数:
    • 如果两个操作数的类型相同,则无需进一步转换
    • 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型 整数类型,则类型为较小整数转换秩的操作数为 已转换为具有更高秩的操作数类型
    • 否则,如果具有无符号整数类型的操作数的秩大于或等于 等于另一个操作数类型的秩,然后为 有符号整数类型转换为无符号的操作数类型 整数类型
    • 否则,如果带符号整数类型的操作数的类型可以表示 具有无符号整数类型的操作数类型的所有值,然后 无符号整数类型的操作数转换为 带符号整数类型的操作数
    • 否则,两个操作数都将转换为无符号整数类型 对应于带符号整数类型的操作数的类型
第6.3.1.1.2节描述了整数促销:

在表达式中使用int或unsigned时,可以使用以下内容 int可用于:

  • 具有整数类型的对象或表达式,其整数转换秩小于或等于int和unsigned的秩 内部的
  • 类型为_Bool、int、signed int或unsigned int的位字段
如果int可以表示原始类型的所有值,则该值为 转换为整数;否则,将转换为无符号整数。 这些被称为整数促销。所有其他类型都是不变的 按整数升迁

char
的秩小于或等于
int
的秩,因此
charsigned char cresult, c1, c2, c3;
c1 = 100;
c2 = 3;
c3 = 4;
cresult = c1 * c2 / c3;