在C++中增加tribool导致从右到左的条件评估

 向着成功一直努力的人 发布于 2023-01-21 23:14

据我所知,C++总是在条件语句中从左到右进行求值

if(A, B, C)

A将被评估第一,B第二,等等.但是,以下示例表现出一些奇怪的行为.

#include 
#include 
#include 
#include 

#include 

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

    std::vector messages_;

private:
    boost::logic::tribool position_;
    std::shared_ptr precedingBlock_ = nullptr;
    std::shared_ptr 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 followingBlock(new FileBlock());

    return 0;
}

示例中有三个版本的条件.据我所知,第一个和最后一个应该评估相同.但是,当我在gdb中跟踪程序时,当我到达条件的第三个版本时,最右边的条件是第一个被评估的条件.

确定条件的范围明显地解决了问题(如条件的第一个版本所示),如同在第二个条件中所示完全删除tribool一样,但我应该能够使用第三个没有发生事故!

由于最左边的条件总是假的,所以程序应该踢出并返回而不做任何事情,但事实并非如此.

这是什么?我不了解tribool吗?我是产生幻觉的吗?

这是我正在使用的mingw构建库存以及已安装的库:

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

这是我的构建命令:

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" 

jrok.. 10

与内置逻辑运算符不同,重载逻辑运算符(并且它们重载boost::tribool)没有从左到右的评估顺序(也没有短路语义).几乎在其他任何地方都没有指定操作数的评估顺序.

1 个回答
  • 与内置逻辑运算符不同,重载逻辑运算符(并且它们重载boost::tribool)没有从左到右的评估顺序(也没有短路语义).几乎在其他任何地方都没有指定操作数的评估顺序.

    2023-01-26 09:37 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有