zoukankan      html  css  js  c++  java
  • 一个三目运算符问题

    最近看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.

    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    转 sql 时间转换格式 convert(varchar(10),字段名,转换格式)
    C#页面添加提交数据后跳出小弹窗的功能
    解决粘包问题
    粘包问题
    模拟ssh远程执行命令
    基于TCP协议的socket套接字编程
    Linux和git使用
    osi七层协议
    TCP协议的三次握手和四次挥手
    C/S 和 B/S架构
  • 原文地址:https://www.cnblogs.com/10087622blog/p/7449088.html
Copyright © 2011-2022 走看看