为什么GCC的三元扩展支持分配? [英] Why doesn't GCC's ternary extension support assignment?

查看:125
本文介绍了为什么GCC的三元扩展支持分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  int x = some_var?:10; //扩展到some_var? some_var:10 

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

  x = x + 2; 

//相反,我们可以说
x + = 2;

既然如此,并且大多数二元C运算符( + - * / | & ^ ),为什么三元扩展操作符不是这种情况:

  int x = ...; 
x?:= 2; //错误:'='令牌之前的预期表达式

//将扩展为
x = x?:2;

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



我真的想在我的代码中做一个很酷的发型笑脸,但我不能!这是设计操作员的疏忽,还是故意在某处出现?是否是操作员短路操作数或其他操作的结果?

解决方案

为了回答这个问题,我相信还有其他一些问题需要回答。


为什么会有运算符,为什么它比code更好
if-else




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

lockquote
<条件表达式通常会导致简洁的代码。




,然后用行来说明

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

这是他们自己的主观,浑浊的意见。就我个人而言,我认为

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

if(i%10 == 9 || i == n-1)
printf(\\\
);
else
printf();

远远更清晰,因为我可以在10秒内阅读并理解代码,而不是1分钟阅读并理解K& R版本。此外,我的代码将整数打印与无关格式分开。但当然,这是我的主观意见,没有明显的对错。至于官方消息,C99理由版本5.10 ,6.5.15并没有真正提到为什么需要?:操作符。它主要只是指出在新标准中操作符的行为已被改变:

lockquote

对条件中间操作数的语法限制
运算符已被放宽以包含不止
逻辑OR表达式:几种现存的实现已采用
这种做法。



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

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



接下来的问题是:


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


对此的回答提及这里


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


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

然后尝试回答原始问题:


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

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

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

除传统和主观编码风格偏好之外,我也找不到任何官方或规范来源表明对?:运算符本身有任何用处。


GCC has an awesome ternary expression extension to C which allows us to create a statement like this:

int x = some_var ?: 10; // expands to some_var ? some_var : 10

Which is really nice, and while it's not particularly intuitive, it does work. Most binary operators in the C language have an additional operator associated with them, which allows for assignment:

x = x + 2;

// instead, we can say
x += 2;

Since this is the case, and the norm for most binary C operators (+, -, *, /, %, |, &, ^), why isn't this the case for the ternary extension operator:

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

// which would expand to
x = x ?: 2;

The only operators which don't support this in standard C are the logical operators (||, &&), which the definitely ternary doesn't fall under, so why can't we do this?

I would really like to make a smiley face with a cool hair-do in my code, but I can't! Was this an oversight in designing the operator, or intentional and documented somewhere? Is it a result of the operator short-circuiting its operand, or something else entirely?

解决方案

To answer the question, I believe there are some other questions that needs to be answered as well.

Why is there a ?: operator in the C language and why is it better than if-else?

As far as I know, nobody has been able to answer that question, without merely stating their own subjective opinions. K&R 2.11 states that

"The conditional expression often leads to succinct code."

and then they illustrate this with the line

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

which is their own subjective, muddy opinion. Personally, I believe that

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

if(i%10==9 || i==n-1)
  printf("\n");
else
  printf(" ");

is far, far clearer since I can read and understand that code in 10 seconds, as opposed to 1 minute to read and understand the K&R version. Also, my code separates the integer printing from the unrelated formatting. But of course, that is my subjective opinion, there is no obvious right or wrong.

As for official sources, the C99 rationale version 5.10, 6.5.15 doesn't really mention why the ?: operator is needed either. It mainly just states that the behavior of the operator has been altered in the new standard:

The syntactic restrictions on the middle operand of the conditional operator have been relaxed to include more than just logical-OR-expression: several extant implementations have adopted this practice.

The type of a conditional operator expression can be void, a structure, or a union; most other operators do not deal with such types. The rules for balancing type between pointer and integer have, however, been tightened, since now only the constant 0 can portably be coerced to a pointer.

So if someone has an urge to perform arithmetic on struct or union types, the ?: is supposedly more handy than if-else. I see no obvious benefit from this, but at least it is some reason for the operator to exist.

The next question would then be:

Why is there a compiler extension to the ?: operand in the GCC compiler?

The answer to this is mentioned here:

When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.

So this GCC extension has nothing to do with readability or language consistency, it was merely added to avoid unwanted side effects.

Then to attempt to answer the original question:

Why doesn't GCC's ternary extension support assignment?

Probably because accessing the lvalue in an assignment condition doesn't typically yield any unwanted side effects. x = x ? : 2; would only have unwanted side effects if x was declared as a volatile - reading a volatile variable is a side effect. So the only practical use I can see with x ?:= 2; would be to prevent someone from accessing the same volatile variable twice in the same conditional expression.

And that is a feature of very narrow and limited value. It would perhaps be useful in some special embedded system case where you read hardware registers in a demanding real-time system... apart from that, I see no uses for it.

Nor can I find any official or canonical sources stating any use for the ?: operator itself, apart from tradition and subjective coding style preferences.

这篇关于为什么GCC的三元扩展支持分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆