升压tribool引起右至左有条件的评价在C ++中 [英] Boost tribool causing right to left conditional evaluation in C++

查看:170
本文介绍了升压tribool引起右至左有条件的评价在C ++中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,C ++总是在条件语句中从左到右评估

 如果(A,B,C)

A 将首先评估 B 第二个,依此类推。但是,下面的例子中展出了一些奇怪的行为。

 的#include<&iostream的GT;
#包括LT&;地图和GT;
#包括LT&;内存和GT;
#包括LT&;矢量>#包括LT&;升压/逻辑/ tribool.hpp>// - ////////////////////////////////////////////
//文件阻止
类FileBlock {
上市:
    FileBlock();
    虚拟〜FileBlock();
    布尔链接();    的std ::矢量<&INT GT; messages_;私人的:
    提高::逻辑:: tribool position_;
    的std :: shared_ptr的< FileBlock> precedingBlock_ = nullptr;
    的std :: shared_ptr的< FileBlock> followingBlock_ = nullptr;
};FileBlock :: FileBlock(){
    性病::法院LT&;< 断点。 <<的std :: ENDL;    //链接()最早由范围进行评估。
    如果(与()){
        如果(!position_
            &功放;&安培; precedingBlock _-> messages_.back()> 1){
                性病::法院LT&;< 无法访问。 <<的std :: ENDL;
        }
    }    //链接()首先评估没有tribool。
    如果(联系()
        &功放;&安培; precedingBlock _-> messages_.back()> 1){
            性病::法院LT&;< 无法访问。 <<的std :: ENDL;
    }    //precedingBlock _-> messages_.back()→1先评估。 (崩溃,因为空。)
    如果(联系()
        &功放;&安培; !位置_
        &功放;&安培; precedingBlock _-> messages_.back()> 1){
            性病::法院LT&;< 无法访问。 <<的std :: ENDL;
    }
}FileBlock ::〜FileBlock(){}布尔FileBlock ::链接(){
    返回false;
}// - ////////////////////////////////////////////
//主
诠释主(){
    的std :: shared_ptr的< FileBlock> followingBlock(新FileBlock());    返回0;
}

有在例如三个版本的条件的。据我所知,第一个和最后应评估相同。然而,正如我跟踪程序在gdb中,当我到达有条件的第三个版本中,最右边的的条件是要评估的第一位。

范围界定条件明显修复该问题(如在有条件的第一个版本证明)一样,完全移除tribool这表现在第二个条件,但我的能够使用的第三个无事!

该计划应该踢出来,没有因为最左边的条件总是假做什么回报,但这种情况并非如此。

这里有什么呢?难道我不理解一些关于tribool?我是幻觉的?

下面是我用MinGW的构建以及安装库的库存:

 核心清单:
  - autoconf2.5-2.68-1
  - autoconf的10-1
  - automake1.11-1.11.1-1
  - binutils的-2.24-1
  - 外籍-2.1.0-1
  - GCC-C ++ - 4.8.1-4
  - GCC核心-4.8.1-4
  - GDB-7.6.1-1
  - gettext的-0.18.3.1-1
  - GMP-5.1.2-1
  - libiconv的-1.14-3
  - 的libltdl-2.4-1
  - libtool的-2.4-1
  - 化妆3.82.90-2
  - mingwrt-4.0.3-1
  - MPC-1.0.1-2
  - MPFR-3.1.2-2
  - pthreads的-w32-2.9.1-1
  - w32api-4.0.3-1
  - wsl_rc-4.0-1
  - zlib的-1.2.8-1辅助库存:
  - wxWidgets的3.0.0
  - 升压1.55
  - YAML-CPP 0.5.1

下面是我的生成命令:

  G ++ -std = GNU ++ 11 -O0 -g3 -Wall -c -fmessage长度= 0 -oSRC \\\\ main.o中.. \\\\ SRC \\\\的main.cpp
G ++ -o wtf.exeSRC \\\\ main.o中


解决方案

与内置的逻辑运算符重载逻辑运算符(和<一个href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/tribool/reference.html#header.boost.logic.tribool_hpp\">they的的重载的boost :: tribool )不用左到右的评估顺序(也不短路语义)。操作数的计算顺序是不确定的,几乎像在其他地方。

To my knowledge, C++ always evaluates from left to right in a conditional statement

if(A, B, C)

A would be evaluated first, B second, so on. However, the following example is exhibiting some odd behavior.

#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include <boost/logic/tribool.hpp>

//-////////////////////////////////////////////
// File Block
class FileBlock {
public:
    FileBlock();
    virtual ~FileBlock();
    bool linked();

    std::vector<int> messages_;

private:
    boost::logic::tribool position_;
    std::shared_ptr<FileBlock> precedingBlock_ = nullptr;
    std::shared_ptr<FileBlock> followingBlock_ = nullptr;
};

FileBlock::FileBlock()  {
    std::cout << "Breakpoint." << std::endl;

    // "linked()" evaluated first by scope.
    if(linked())    {
        if(!position_
            && precedingBlock_->messages_.back() > 1)   {
                std::cout << "Unreachable." << std::endl;
        }
    }

    // "linked()" evaluated first without the tribool.
    if(linked()
        && precedingBlock_->messages_.back() > 1)   {
            std::cout << "Unreachable." << std::endl;
    }

    // "precedingBlock_->messages_.back() > 1" evaluated first. (Crash because null.)
    if(linked()
        && !position_
        && precedingBlock_->messages_.back() > 1)   {
            std::cout << "Unreachable." << std::endl;
    }
}

FileBlock::~FileBlock() {}

bool FileBlock::linked()    {
    return false;
}

//-////////////////////////////////////////////
// main
int main()  {
    std::shared_ptr<FileBlock> followingBlock(new FileBlock());

    return 0;
}

There are three versions of the conditional in the example. To my knowledge, the first and last should evaluate the same. However, as I trace the program in gdb, when I reach the third version of the conditional, the right most condition is the first to be evaluated.

Scoping the conditional obviously fixes the issue (as demonstrated in the first version of the conditional), as does removing the tribool altogether as demonstrated in the second conditional, but I should be able to use the third one without incident!

The program should kick out and return without doing anything since the left most condition is always false, but this is not the case.

What is up here? Am I not understanding something about tribool? Am I hallucinating?

Here's a inventory of the mingw build I'm using as well as the installed libraries:

Core Inventory:
 - autoconf2.5-2.68-1
 - autoconf-10-1
 - automake1.11-1.11.1-1
 - binutils-2.24-1
 - expat-2.1.0-1
 - gcc-c++-4.8.1-4
 - gcc-core-4.8.1-4
 - gdb-7.6.1-1
 - gettext-0.18.3.1-1
 - gmp-5.1.2-1
 - libiconv-1.14-3
 - libltdl-2.4-1
 - libtool-2.4-1
 - make-3.82.90-2
 - mingwrt-4.0.3-1
 - mpc-1.0.1-2
 - mpfr-3.1.2-2
 - pthreads-w32-2.9.1-1
 - w32api-4.0.3-1
 - wsl_rc-4.0-1
 - zlib-1.2.8-1

Auxiliary Inventory:
 - wxWidgets 3.0.0
 - Boost 1.55
 - yaml-cpp 0.5.1

Here are my build commands:

g++ -std=gnu++11 -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\main.o" "..\\src\\main.cpp" 
g++ -o wtf.exe "src\\main.o" 

解决方案

Unlike built-in logical operators, overloaded logical operators (and they are overloaded for boost::tribool) don't have left-to-right order of evaluation (nor short-circuit semantics). The order of evaluation of operands is unspecified like almost everywhere else.

这篇关于升压tribool引起右至左有条件的评价在C ++中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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