Boost Tribol导致C++中从右到左的条件求值
Boost tribool causing right to left conditional evaluation in C++
据我所知,C++在条件语句中总是从左到右求值
if(A, B, C)
首先评估A
,其次评估B
,依此类推。然而,下面的示例显示出一些奇怪的行为。
#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;
}
示例中有三个版本的条件。据我所知,第一个和最后一个应该评估相同。然而,当我在gdb中跟踪程序时,当我到达条件的第三个版本时,最右边的条件是第一个要评估的。
界定条件显然解决了这个问题(如条件的第一个版本所示),正如第二个条件所示,完全去除Tribol一样,但我应该能够使用第三个条件而不会发生意外!
程序应该在不做任何事情的情况下退出并返回,因为最左边的条件总是错误的,但事实并非如此。
上面是什么?我是不是不了解Tribol?我有幻觉吗?
以下是我正在使用的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"
与内置逻辑运算符不同,重载逻辑运算符(它们对于boost::tribool
是重载的)没有从左到右的求值顺序(也没有短路语义)。操作数的求值顺序与其他所有操作数一样都是未指定的。
相关文章:
- 是否可以在 RTL(从右到左)中制作控制台输出?
- 在if条件下,右或左改变值的相等性检查是否有任何区别
- 为什么此右值引用绑定到左值?
- 从右到左隔离字符串.C++
- 将右值绑定到左值引用
- 为什么右值引用类型的模板参数可以绑定到左值类型?
- 使用“void*”将右值引用绑定到左值
- 右值到左值转换
- 从右到左计算当前索引中的数据结构中的元素数,并打印每个元素的计数
- 如何从右到左展开参数包
- 如何在包含 typedef 时用从右到左的规则解释变量声明
- 如何确定数字是否具有从右到左升序的数字
- Boost Tribol导致C++中从右到左的条件求值
- 如何用从右到左的语言进行输出
- 是从右到左计算的 C++11 赋值表达式
- 你如何让一个向量从右到左阅读
- 使用方向枚举列表时反转方向(从左到右或从上到下)
- Outlook表单区域从右到左从c++代码
- 从右到左的阅读顺序:为什么不自动计算?
- 在文件中从右向左写入数据