我有以下代码:
#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 ++。
答案 0 :(得分:3)
bool b;
// Set b to 123
char *p = (char*)&b;
*p = 123;
C ++标准未指定bool
的存储方式......例如一个编译器使用一个字节而另一个使用四个字节完全合法。此外,一个编译器可以为0
存储说false
,为true
和另一个0
和1
以及其他任何值存储所有位。所有重要的是,当在布尔上下文中使用时,逻辑正常工作,并且在转换为int
时或从int(b)
转换时:
1
为b
,则 true
为0
,如果b
为false
,则为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
的价值的问题:标准从未实际指定。它确实指定true
是bool
类型可以表示的两个值之一(当然另一个是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