加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在C/C++中,使用布尔运算符短路控制流是否安全而不使用计算的布尔

发布时间:2020-12-16 09:58:49 所属栏目:百科 来源:网络整理
导读:一段继承代码中的重复模式是,只要其中一个函数返回某个值,就会调用一系列函数并中止链.然后该值应用于后续计算.为了演示,破坏值为0.请考虑以下程序: #include stdio.hstatic int n;static int foo(int x){ fprintf(stderr,"%d(%d) ",x,n++); return x ? 0 :
一段继承代码中的重复模式是,只要其中一个函数返回某个值,就会调用一系列函数并中止链.然后该值应用于后续计算.为了演示,破坏值为0.请考虑以下程序:

#include <stdio.h>

static int n;

static int foo(int x)
{
    fprintf(stderr,"%d(%d) ",x,n++);
    return x ? 0 : n;
}

static void with_if(void)
{
    int rc;
    n = 0;

    do {
        if( (rc = foo(1)) ) break;
        if( (rc = foo(2)) ) break;
        if( (rc = foo(3)) ) break;
        if( (rc = foo(4)) ) break;
        if( (rc = foo(0)) ) break;
        if( (rc = foo(5)) ) break;
    } while(0);

    fprintf(stderr,">>%d<<n",rc);
}

void with_short_circuit(void)
{
    int rc;
    n = 0;

       (rc = foo(1))
    || (rc = foo(2))
    || (rc = foo(3))
    || (rc = foo(4))
    || (rc = foo(0))
    || (rc = foo(5));

    fprintf(stderr,rc);
}

int main(int argc,char *argv[])
{
    with_if();
    with_short_circuit();
    return 0;
}

请注意,短路变体不仅更简洁,它(IMHO)也更容易阅读和推理,因为在阅读该代码时,您不必将所有其他周围语句推入您的心理堆栈.所以我大多喜欢短路的变种.

就GCC-4.9.3和Clang-3.6.2而言,with_if和with_short_circuit是相同的(它们产生相同的汇编输出).

我担心的是,布尔运算符链的结果被忽略(如果用-Wall GCC编译发出关于它的警告,Clang仍保持沉默)并且这可能被视为优化的机会.当然调用foo会产生副作用,因此在我对C语言标准的理解中应该可以安全地使用布尔短路来控制流程.有点我不太确定.

解决方法

这被称为“丢弃值表达式”,必须进行评估:

N4296,5§11:

In some contexts,an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读