一个三目运算符问题

来源:互联网 发布:java服务端开发技术 编辑:程序博客网 时间:2024/06/06 11:01

最近看bbr相关的代码,tcp_rate_check_app_limited函数中计算tp->app_limited为:
tp->app_limited =
(tp->delivered + tcp_packets_in_flight(tp)) ? : 1;

这个三目运算符中间表达式为空,通过简单测试发现返回的是第一个表达式的值。

int a =3;
int b =(a?:0);

相应的汇编代码是:
=> 0x000000000040047f <+11>: movl $0x3,-0x8(%rbp)
0x0000000000400486 <+18>: mov -0x8(%rbp),%eax
0x0000000000400489 <+21>: mov %eax,-0x4(%rbp)

我们惊奇地发现将第一个表达式的值赋值给了b,而连比较的动作都没有,按照之前的理解,至少应该出现一个比较语句啊,ok,修改代码如下:

int a =0;
int b =(a?:(a=3));

相应的汇编是:
=> 0x000000000040047f <+11>: movl $0x0,-0x8(%rbp)
0x0000000000400486 <+18>: mov -0x8(%rbp),%eax
0x0000000000400489 <+21>: test %eax,%eax
0x000000000040048b <+23>: je 0x40048f <main+27>
0x000000000040048d <+25>: jmp 0x400499 <main+37>
0x000000000040048f <+27>: movl $0x3,-0x8(%rbp)
0x0000000000400496 <+34>: mov -0x8(%rbp),%eax
0x0000000000400499 <+37>: mov %eax,-0x4(%rbp)

我们看到了熟悉的比较语句,同时最终b为3.


查看gcc相关解释如下:
Conditionals with Omitted Operands

The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero,
its value is the value of the conditional expression.

Therefore, the expression

x ? : y

has the value of x if that is nonzero; otherwise, the value of y.

This example is perfectly equivalent to

x ? x : y

In this simple case, the ability to omit the middle operand is not especially useful. 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.


很明白了。

另外,关于side effect:
side effect是关于计算(Evaluation)表达式的效应之一。譬如 int i; 计算 i = 3 这个表达式会得到一个值3,但同时变量i也被赋值了,这赋值的效应就是side effect。不是所有计算都有副效应,例如 计算2+3 得到值5,但没有side effect。
side effect的标准定义是:Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,which are changes in the state of the execution environment.