布尔值

时间:2015-09-26 16:44:06

标签: c++ language-lawyer

考虑以下程序,测试boolean转换回布尔值的移位运算符的结果:

#include <iostream>
int main()
{
    std::cout<<"right shift: bool/bool"<<std::endl;
    std::cout<<"false << false = "<<bool(false << false)<<std::endl;
    std::cout<<"false << true = "<<bool(false << true)<<std::endl;
    std::cout<<"true << false = "<<bool(true << false)<<std::endl;
    std::cout<<"true << true = "<<bool(true << true)<<std::endl;
    std::cout<<std::endl;
    std::cout<<"right shift: bool/unsigned int"<<std::endl;
    std::cout<<"false << 0U = "<<bool(false << 0U)<<std::endl;
    std::cout<<"false << 1U = "<<bool(false << 1U)<<std::endl;
    std::cout<<"false << 2U = "<<bool(false << 2U)<<std::endl;
    std::cout<<"false << 100U = "<<bool(false << 100U)<<std::endl;
    std::cout<<"true << 0U = "<<bool(true << 0U)<<std::endl;
    std::cout<<"true << 1U = "<<bool(true << 1U)<<std::endl;
    std::cout<<"true << 2U = "<<bool(true << 2U)<<std::endl;
    std::cout<<"true << 100U = "<<bool(true << 100U)<<std::endl;
    std::cout<<std::endl;
    std::cout<<"right shift: bool/int"<<std::endl;
    std::cout<<"false << -100 = "<<bool(false << -100)<<std::endl;
    std::cout<<"false << -2 = "<<bool(false << -2)<<std::endl;
    std::cout<<"false << -1 = "<<bool(false << -1)<<std::endl;
    std::cout<<"false << 0 = "<<bool(false << 0)<<std::endl;
    std::cout<<"false << 1 = "<<bool(false << 1)<<std::endl;
    std::cout<<"false << 2 = "<<bool(false << 2)<<std::endl;
    std::cout<<"false << 100 = "<<bool(false << 100)<<std::endl;
    std::cout<<"true << -100 = "<<bool(true << -100)<<std::endl;
    std::cout<<"true << -2 = "<<bool(true << -2)<<std::endl;
    std::cout<<"true << -1 = "<<bool(true << -1)<<std::endl;
    std::cout<<"true << 0 = "<<bool(true << 0)<<std::endl;
    std::cout<<"true << 1 = "<<bool(true << 1)<<std::endl;
    std::cout<<"true << 2 = "<<bool(true << 2)<<std::endl;
    std::cout<<"true << 100 = "<<bool(true << 100)<<std::endl;
    std::cout<<std::endl;
    std::cout<<"left shift: bool/bool"<<std::endl;
    std::cout<<"false >> false = "<<bool(false >> false)<<std::endl;
    std::cout<<"false >> true = "<<bool(false >> true)<<std::endl;
    std::cout<<"true >> false = "<<bool(true >> false)<<std::endl;
    std::cout<<"true >> true = "<<bool(true >> true)<<std::endl;
    std::cout<<std::endl;
    std::cout<<"left shift: bool/unsigned int"<<std::endl;
    std::cout<<"false >> 0U = "<<bool(false >> 0U)<<std::endl;
    std::cout<<"false >> 1U = "<<bool(false >> 1U)<<std::endl;
    std::cout<<"false >> 2U = "<<bool(false >> 2U)<<std::endl;
    std::cout<<"false >> 100U = "<<bool(false >> 100U)<<std::endl;
    std::cout<<"true >> 0U = "<<bool(true >> 0U)<<std::endl;
    std::cout<<"true >> 1U = "<<bool(true >> 1U)<<std::endl;
    std::cout<<"true >> 2U = "<<bool(true >> 2U)<<std::endl;
    std::cout<<"true >> 100U = "<<bool(true >> 100U)<<std::endl;
    std::cout<<std::endl;
    std::cout<<"left shift: bool/int"<<std::endl;
    std::cout<<"false >> -100 = "<<bool(false >> -100)<<std::endl;
    std::cout<<"false >> -2 = "<<bool(false >> -2)<<std::endl;
    std::cout<<"false >> -1 = "<<bool(false >> -1)<<std::endl;
    std::cout<<"false >> 0 = "<<bool(false >> 0)<<std::endl;
    std::cout<<"false >> 1 = "<<bool(false >> 1)<<std::endl;
    std::cout<<"false >> 2 = "<<bool(false >> 2)<<std::endl;
    std::cout<<"false >> 100 = "<<bool(false >> 100)<<std::endl;
    std::cout<<"true >> -100 = "<<bool(true >> -100)<<std::endl;
    std::cout<<"true >> -2 = "<<bool(true >> -2)<<std::endl;
    std::cout<<"true >> -1 = "<<bool(true >> -1)<<std::endl;
    std::cout<<"true >> 0 = "<<bool(true >> 0)<<std::endl;
    std::cout<<"true >> 1 = "<<bool(true >> 1)<<std::endl;
    std::cout<<"true >> 2 = "<<bool(true >> 2)<<std::endl;
    std::cout<<"true >> 100 = "<<bool(true >> 100)<<std::endl;
    std::cout<<std::endl;
    return 0;
}

它在我的电脑上产生以下输出:

right shift: bool/bool
false << false = 0 // Well defined
false << true = 0 // Well defined
true << false = 1 // Well defined
true << true = 1 // Well defined

right shift: bool/unsigned int
false << 0U = 0 // Well defined
false << 1U = 0 // Well defined
false << 2U = 0 // ?
false << 100U = 0 // Undefined behaviour
true << 0U = 1 // Well defined
true << 1U = 1 // Well defined
true << 2U = 1 // ?
true << 100U = 0 // Undefined behaviour

right shift: bool/int
false << -100 = 0 // Undefined behaviour
false << -2 = 0 // Undefined behaviour
false << -1 = 0 // Undefined behaviour
false << 0 = 0 // Well defined
false << 1 = 0 // Well defined
false << 2 = 0 // ?
false << 100 = 0 // Undefined behaviour
true << -100 = 0 // Undefined behaviour
true << -2 = 0 // Well defined
true << -1 = 0 // Well defined
true << 0 = 1 // Well defined
true << 1 = 1 // Well defined
true << 2 = 1 // ?
true << 100 = 0  // Undefined behaviour

left shift: bool/bool
false >> false = 0 // Well defined
false >> true = 0 // Well defined
true >> false = 1 // Well defined
true >> true = 0 // Well defined

left shift: bool/unsigned int
false >> 0U = 0 // Well defined
false >> 1U = 0 // Well defined
false >> 2U = 0 // ?
false >> 100U = 0  // Undefined behaviour
true >> 0U = 1 // Well defined
true >> 1U = 0 // Well defined
true >> 2U = 0 // ?
true >> 100U = 0  // Undefined behaviour

left shift: bool/int
false >> -100 = 0  // Undefined behaviour
false >> -2 = 0  // Undefined behaviour
false >> -1 = 0  // Undefined behaviour
false >> 0 = 0 // Well defined
false >> 1 = 0 // Well defined
false >> 2 = 0 // ?
false >> 100 = 0  // Undefined behaviour
true >> -100 = 0  // Undefined behaviour
true >> -2 = 1  // Undefined behaviour
true >> -1 = 1  // Undefined behaviour
true >> 0 = 1 // Well defined
true >> 1 = 0 // Well defined
true >> 2 = 0 // ?
true >> 100 = 0  // Undefined behaviour

C ++标准部分5.8 expr.shift描述了移位运算符的行为,但我想确保理解它。因此,我想知道我测试的每一行,该行是“良好定义的行为和独立于实现”,还是“依赖于实现/未定义的行为”。

编辑:我预先填写了,所以我只需要一个确认,以及关于我不知道的案例的答案(注明?

1 个答案:

答案 0 :(得分:3)

只有少数案例需要考虑。我们将E1称为提升的左操作数,将E2称为提升的右操作数。 未定义的行为案例包括:

  • 如果E2“为负数,或大于或等于”E1
  • 的位数长度
  • E1 << E2中,如果E1已签名,则为< 一个。负
    湾E1×2 E2 不是“可表示的 在结果类型“
  • 的相应无符号类型中

实现定义的行为案例是:

  • E1 >> E2,如果E1“有签名类型和否定值。”

其他一切都很明确。

标有?的案例都是明确定义的。 E1E2永远不会消极,E2也不会接近32,所以不用担心溢出。所有都是明确定义的int