【问题标题】:Does Unary + operator do type conversions?一元 + 运算符是否进行类型转换?
【发布时间】:2014-09-08 10:41:06
【问题描述】:

直到现在我还相信没有使用一元 + 运算符。

但后来我遇到了以下示例:

char ch;
short sh;
int i;

printf("%d %d %d",sizeof(ch),sizeof(sh),sizeof(i)); // output: 1 2 4

printf("%d %d %d",sizeof(+ch),sizeof(+sh),sizeof(i)); // output: 4 4 4

是不是说+在这里做类型转换?

因为它的行为与以下相同

printf("%d %d %d",sizeof((int)ch),sizeof((int)sh),sizeof(i)); // output: 4 4 4

这迫使我认为+ 正在做类型转换。

但后来我在double 上试了一下

double f;
printf("%d %d",sizeof(+f),sizeof((int)f),sizeof(f));  // output: 8 4 8

这迫使我重新考虑一元 + 运算符。

所以我的第二个问题是:一元+ 运算符对sizeof 运算符有特殊作用吗?

【问题讨论】:

  • double 让您感到困惑的是什么?对于您的第一个问题:是的,+ 进行转换(IIRC 整数提升,所以float 没有得到double,但整数得到(无符号)int 或更高等级的东西)。

标签: c sizeof unary-operator integer-promotion


【解决方案1】:

一元 + 对其操作数执行整数提升,我们可以通过查看 C99 标准部分草案 6.5.3.3 一元算术运算符 看到这一点,它说 (强调我的未来):

一元+运算符的结果是它的(提升)的值 操作数。 整数提升在操作数上执行,并且 结果具有提升的类型。

6.3.1 部分 算术操作数 说:

如果一个 int 可以表示原始类型的所有值,则该值为 转换为 int;否则,它将转换为无符号整数。 这些被称为整数促销48)所有其他类型都是 整数促销保持不变。

请注意,整数提升不会改变所有其他类型,因此 double 保持为 double。这也适用于 float,它不会被提升为 double

另请注意,将%d 用于sizeof 的结果是未定义的行为,因为结果是size_t。正确的格式说明符是%zu

【讨论】:

  • 感谢您提到 sizeof 的 %zu 格式说明符,我以前从未听过它
  • " using %d for the result of sizeof is undefined behavior" 在上面的问题中,当我们得到意外行为时,它给出了预期的结果?
  • @yanivx undefined behavior 表示它是不可预测的,因此以一种看似合理的方式行事可能是一种未定义的行为。但是我们可以找到很多情况,例如this one,编译器会冒昧地做一些意想不到的事情。有很多 UB 可以满足您的期望,但将来可能不会。
【解决方案2】:

当较大类型的表达式中涉及较小类型时(例如,char 小于 short大部分小于 int可能 小于long),所涉及的类型提升到较大的类型。

所以是的,当您使用一元 + 运算符时,您会得到一个 int,因为 int 是 C 中的自然整数类型。

关于double 类型,C 的自然浮点类型是double,这就是为什么没有提升已经是double 类型的值或变量的原因。

sizeof 运算符与此无关。

【讨论】:

  • 如果你要采取预防措施,char 也只比short 小很多。仅处理一种数据宽度的处理器(如 DSP)可以在符合标准的 C 编译器中编程,其中 charshortint 都具有相同的宽度(可以是 16 位、24 位位或 32 位,例如)。
  • 在第一段中,您说提升发生在“涉及较小类型时......较大类型”,但一元 + 的操作数不涉及其他类型(较大或其他类型)在那个表达中。所以第二段不是从第一段开始的,即使它在其他方面是正确的。
  • @EliasVanOotegem 这正是为什么int8_t 仅在它存在时才被定义的原因,以及为什么我们有int_least8_t。如果总是定义int8_t,那么int_least8_t 将没有意义,因为它只能是int8_tstackoverflow.com/a/5254321/139746
  • @PascalCuoq:好吧,那让我闭嘴:D,好点。表明我该收工了
  • @Joachim short 被转换为 int 因为 int 是 integers 的自然类型,同样如果 double 是 float 的自然类型,那么它会转换为 double 吗?
【解决方案3】:

一元运算符+ 触发“初始”通常的算术转换,因此所有整数操作数,其等级低于intunsigned int 的等级都会提升为int(或 unsigned int 如果 int 类型不涵盖在该实现上提升的类型的所有值)。

【讨论】:

    【解决方案4】:

    不是sizeof,而是一元+ 本身。一元 + 的操作数经过“通常的算术转换”。参见,例如,涉及普通加法的this other answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-03
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 2023-03-29
      相关资源
      最近更新 更多