【问题标题】:Ternary (conditional) expression has the wrong type三元(条件)表达式的类型错误
【发布时间】:2017-11-16 00:50:43
【问题描述】:

我发现这两个实现不相等:

1.num = sign ? (int)va_arg(args, int) : (unsigned int)va_arg(args, unsigned int);

2.if (sign)
    num = (int)va_arg(args, int);
else    
    num = (unsigned int)va_arg(args, unsigned int);

第一个实现,无论符号是什么值,它总是选择假分支。

第二个按预期工作。

这里发生了什么?我正在使用 GCC/ARM GCC 64 位

【问题讨论】:

  • 第一个不“始终选择假分支”,但条件的结果总是unsigned int,即选择true分支,该值将是(unsigned int)(int)va_arg(args, int),这很可能等于你从错误分支中得到的结果
  • @Leslie Li 我认为你错了。问题是有符号整数和无符号整数的共同类型是无符号整数。
  • 要改进问题,请说明您如何确定选择了错误分支
  • 并且还要给出num的类型。这很重要。
  • 是的,每个表达式在编译时都有它的类型(除了可变修改数组的数组大小);条件的结果也不例外

标签: c gcc conditional-operator


【解决方案1】:

我猜您遇到的问题是 ?: 运算符中发生的微妙的隐式提升。第二个和第三个操作数通过通常的算术转换相互平衡。这是 C11 6.5.15 规定的:

如果第二个和第三个操作数都具有算术类型,则结果 由通常的算术转换确定的类型, 它们是否应用于这两个操作数,是结果的类型。

意思是如果一个是有符号的而另一个是无符号的,有符号的操作数会被转换为无符号的。无论第二个或第三个操作数中的哪一个被评估并用作结果,都会发生这种情况。

如果您不知道这种奇怪现象,这可能会导致奇怪的错误:

#include <stdio.h>

int main (void)
{
  int x;
  if( (-1 ? (printf("Expression evaluates to -1\n"),-1) : 0xFFFFFFFF) < 0)
  {
    printf("-1 is < 0");
  }
  else
  {
    printf("-1 is >= 0");
  }
}

输出:

Expression evaluates to -1
-1 is >= 0

这就是为什么if/else?: 更受欢迎的原因。

【讨论】:

    猜你喜欢
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2023-03-19
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多