将bool更改为0或1以外的值?

时间:2015-01-29 05:56:01

标签: c++ visual-studio-2010 visual-c++

我有以下代码:

#include <stdio.h>

int main()
{
    bool b;

    // Set b to 123
    char *p = (char*)&b;
    *p = 123;

    // Check if b is considered to be true
    if (b == true) printf("b is true");

    return 0;
}

b不被视为true,那么true究竟意味着什么,true等于1


编辑: 忘了说我使用的是Visual C ++。

3 个答案:

答案 0 :(得分:3)

bool b;

// Set b to 123
char *p = (char*)&b;
*p = 123;

C ++标准未指定bool的存储方式......例如一个编译器使用一个字节而另一个使用四个字节完全合法。此外,一个编译器可以为0存储说false,为true和另一个01以及其他任何值存储所有位。所有重要的是,当在布尔上下文中使用时,逻辑正常工作,并且在转换为int时或从int(b)转换时:

    如果1b,则
  • true0,如果bfalse,则为bool(n)

  • true n if {and-only-if 0不是bool

因此,在测试布尔值时,可能会或可能不会查询int表示中最低内存地址的字符:它可能是一个编译器生成的代码使用四字节{{然后读取的只有最低有效位或字节被测试,这取决于字节顺序 - *p = 123可能没有触及。类似地,编译器可能会将值读入有符号整数寄存器并测试否定性(期望true时的全比特值),即使*p = 123仅写入// Check if b is considered to be true if (b == true) printf("b is true"); 也可能失败或最重要的字节。

因此 - 即使没有其他事情发生 - 下面的行可能不会报告“b是真的”......

bool

......但是这个测试还有进一步的缺陷......

  • 可能从bool表示中的其他字节读取尚未初始化的内容(未初始化的内存读取具有未定义的行为)

  • 单独摆弄bool值本身就有“未定义的行为”;就bool内存的“二进制写入”而言,只有来自另一个正确初始化bool的完整的逐字节副本才能保证{{1}}处于可用状态

答案 1 :(得分:1)

C ++ 11说(3.9&#34; Types&#34; [basic.types]):

  

对象的值表示是保存对象的位集   类型T的值。对于简单的可复制类型,值   表示是对象表示中的一组位   确定一个值,它是一个离散元素   实现定义的值集

和(3.9.1&#34;基本类型&#34; [basic.fundamental]):

  

对于字符类型,对象表示的所有位都参与其中   在价值表示中。对于无符号字符类型,全部   值表示的可能位模式表示数字。   这些要求不适用于其他类型

     

...

     

bool类型的值为true或false

最后,5&#34;表达式&#34; [expr]说:

  

如果在评估表达式期间,结果不是   数学定义或不在可表示值的范围内   它的类型,行为是未定义的。

当您将值123写入bool对象占用的内存(通过char* p)时,您正在编写的内容不会是代表bool对象的价值表示&#39;。因此,当您随后通过左值b访问该对象时,程序会显示未定义的行为,并且您的bool对象既不是true也不是false

并回答关于true的价值的问题:标准从未实际指定。它确实指定truebool类型可以表示的两个值之一(当然另一个是false)。该标准还规定true容易转换为1,反之亦然,1易于转换为true。这些转换过于自然而轻松地发生,我认为几乎每个人都认为true的值为1。

要记住的一件事是,几乎任何非零积分值都会很容易转换为true - 而不仅仅是1.但是,在您的示例中,对于值123没有发生这种情况,因为在该表达式中正在写入char类型的左值,因此不会转换为bool

答案 2 :(得分:0)

true表示1

但123也被认为是真的(通常所有整数除了零)

如果你说

if (b) printf("b is true");

您必须获得输出b is true