奇怪的C布尔铸造行为(true!= true)
只是在大学内部阅读:
#include <iostream> using namespace std; union zt { bool b; int i; }; int main() { zt w; bool a,b; a=1; b=2; cerr<<(bool)2<<static_cast<bool>(2)<<endl; //11 cerr<<a<<b<<(a==b)<<endl; //111 w.i=2; int q=w.b; cerr<<(bool)q<<q<<w.b<<((bool)((int)w.b))<<w.i<<(w.b==a)<<endl; //122220 cerr<<((w.b==a)?'T':'F')<<endl; //F } 所以a,b和w.b都被声明为bool. a被分配1,b被分配2,并且w.b的内部表示被改变为2(使用联合). 这样,所有的a,b和w.b都是真的,但是a和w.b不会相等,所以这可能意味着宇宙被破坏(true!= true) 我知道这个问题比实际更理论(一个程序员不想改变一个bool的内部表示),但这里是问题: 这是可以吗? (这是用g 4.3.3测试的)我的意思是,编译器应该知道,在布尔比较期间,任何非零值可能意味着真实吗? 编辑: 三件事: > bool和int有不同的大小,没关系.但是如果我使用char而不是int.或者当sizeof(bool)== sizeof(int)? 解决方法
非零的任何整数值(或非NULL的指针)都表示为true.
这是一个真正的问题.
如果我们去最后一个代码示例,那么a和b都是bool,并且通过分配1和2来设置为true(否则1和2消失,它们现在只是真的). 所以打破你的表情: a!=0 // true (a converted to 1 because of auto-type conversion) b!=0 // true (b converted to 1 because of auto-type conversion) ((a!=0) && (b!=0)) => (true && true) // true ( no conversion done) a==0 // false (a converted to 1 because of auto-type conversion) b==0 // false (b converted to 1 because of auto-type conversion) ((a==0) && (b==0)) => (false && false) // false ( no conversion done) ((a!=0) && (b!=0)) || ((a==0) && (b==0)) => (true || false) => true 所以我总是期望上面的表达式得到很好的定义,并且始终是真实的. 但我不知道这是如何适用于您的原始问题.当将一个整数分配给bool时,整数将转换为bool(如上所述). true的实际表示不是由标准定义的,可以是适合bool的任何位模式(您不能假定任何特定的位模式). 当将bool与int进行比较时,将bool转换为int,然后进行比较.
以二进制格式编写数据是不可知的. >整数(有endianess) 所有这些您需要知道底层硬件和编译器.编译器的不同编译器或不同版本的编译器,甚至具有不同优化标记的编译器可能对上述所有操作都有不同的行为. 联盟的问题 struct X { int a; bool b; }; 当人们提到写“a”,然后从’b’读取是未定义的. 所以除非你了解你的硬件和你的编译器的行为将是意想不到的. 因此,这些用途是未定义的,但不被标准所禁止.他们被允许的原因是你可能已经做了这个研究,发现在你的系统上使用这个特定的编译器,你可以做一些自由的优化,做出这些假设.但是请注意,假设中的任何更改将会破坏您的代码. 另外当比较两种类型时,编译器将在比较之前进行一些自动转换,请记住在比较之前将两种类型转换为相同类型.为了在整数和bool之间进行比较,将bool转换为整数,然后与另一个整数进行比较(转换将false转换为0,并将其转换为1).如果要转换的对象都是bool,那么不需要转换,并且使用布尔逻辑进行比较. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |