为什么GCC的三元扩展不支持分配?

Ric*_*III 5 c gcc ternary-operator gcc-extensions

GCC有一个令人敬畏的三元表达式扩展到C,它允许我们创建一个这样的语句:

int x = some_var ?: 10; // expands to some_var ? some_var : 10
Run Code Online (Sandbox Code Playgroud)

这真的很好,虽然它不是特别直观,但确实有效.C语言中的大多数二元运算符都有一个与之关联的附加运算符,允许赋值:

x = x + 2;

// instead, we can say
x += 2;
Run Code Online (Sandbox Code Playgroud)

既然是这样的话,对于大多数二进制C运营商(常态+,-,*,/,%,|,&,^),为什么不是这样的三元扩展操作的情况下:

int x = ...;
x ?:= 2; // error: Expected expression before '=' token

// which would expand to
x = x ?: 2;
Run Code Online (Sandbox Code Playgroud)

唯一在标准C中支持此操作符的运算符是逻辑运算符(||,&&),它们绝对不属于三元组,为什么我们不能这样做呢?

在我的代码中,我真的想用一个很酷的头发做一个笑脸,但我不能!这是设计操作员的疏忽,还是故意和记录在某处?是运营商将其操作数短路还是完全不同的结果?

Lun*_*din 7

为了回答这个问题,我认为还有一些其他问题需要回答.

为什么?:C语言中有一个运算符,为什么它比它好if-else

据我所知,没有人能够回答这个问题,而不仅仅是陈述自己的主观意见.K&R 2.11指出

"条件表达式通常会导致简洁的代码."

然后他们用线说明了这一点

printf("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');
Run Code Online (Sandbox Code Playgroud)

这是他们自己的主观,泥泞的意见.我个人认为

printf("%6d", a[i]);

if(i%10==9 || i==n-1)
  printf("\n");
else
  printf(" ");
Run Code Online (Sandbox Code Playgroud)

因为我可以在10秒内阅读并理解该代码,而不是1分钟阅读和理解K&R版本,所以远远更加清晰.此外,我的代码将整数打印与不相关的格式分开.但当然,这是我的主观意见,没有明显的对错.

至于官方消息来源,C99基本原理版本5.10,6.5.15并没有真正提到为什么需要?:运算符.它主要只是说新运营商的行为在新标准中有所改变:

对条件运算符的中间操作数的句法限制已经放宽,不仅包括逻辑OR表达式:现有的几种实现都采用了这种做法.

条件运算符表达式的类型可以是void,结构或联合; 大多数其他运营商不处理此类型.然而,在指针和整数之间平衡类型的规则已经收紧,因为现在只有常量0可以被强制转换为指针.

因此,如果某人有对结构或联合类型执行算术的冲动,那么?:应该比if-else更方便.我认为没有明显的好处,但至少这是运营商存在的一些原因.

接下来的问题是:

为什么?:GCC编译器中的操作数有编译器扩展?

这里提到答案:

当它变得有用时是第一个操作数,或者可能(如果它是一个宏参数),包含副作用.然后在中间重复操作数将执行两次副作用.省略中间操作数使用已经计算的值而没有重新计算它的不良影响.

因此,这个GCC扩展与可读性或语言一致性无关,它只是为了避免不必要的副作用而添加.

然后尝试回答原始问题:

为什么GCC的三元扩展不支持分配?

可能是因为在赋值条件下访问左值通常不会产生任何不需要的副作用.x = x ? : 2;如果x被声明为a,则只会产生不必要的副作用volatile- 读取volatile变量是副作用.因此,我可以看到的唯一实际用途x ?:= 2;是阻止某人在同一条件表达式中两次访问相同的volatile变量.

这是一个非常狭窄且价值有限的特征.它可能在某些特殊的嵌入式系统中很有用,在这种情况下,您可以在要求苛刻的实时系统中读取硬件寄存器......除此之外,我认为没有用处.

除了传统和主观编码风格偏好之外,我也找不到任何官方或规范来源说明?:运算符本身的任何用途.

  • 也许不同寻常的是,我们达成了一致意见;-) K&R通过使用一个可能不太明显的例子设法射击自己.`?:`确实可以让代码更简洁,更清晰 - 但是他们的例子不是其中之一!运算符允许使用表达式,否则将需要控制流 - 这有时是有用的. (2认同)