#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(使用联合).@H_502_5@
这样,所有的a,b和w.b都是真的,但是a和w.b不会相等,所以这可能意味着宇宙被破坏(true!= true)@H_502_5@
我知道这个问题比实际更理论(一个程序员不想改变一个bool的内部表示),但这里是问题:@H_502_5@
这是可以吗? (这是用g 4.3.3测试的)我的意思是,编译器应该知道,在布尔比较期间,任何非零值可能意味着真实吗?
>你知道这个角落可能成为一个真正的问题的任何情况吗? (例如在从流中加载二进制数据时)@H_502_5@
编辑:@H_502_5@
三件事:@H_502_5@
> bool和int有不同的大小,没关系.但是如果我使用char而不是int.或者当sizeof(bool)== sizeof(int)?
>请尽可能回答我问的两个问题.我实际上也对第二个问题的答案感兴趣,因为在我的诚实意见中,在嵌入式系统(可能是8位系统)中,这可能是一个真正的问题(或不是).
>新问题:这是真的未定义的行为吗?如果是,为什么?如果没有,为什么?在规范中的布尔比较运算符中是否没有任何假设?@H_502_5@解决方法
Is this okay? (this was tested with g++ 4.3.3) I mean,should the compiler be aware that during boolean comparison any non-zero value might mean true?
非零的任何整数值(或非NulL的指针)都表示为true.
但是当比较整数和bool时,在比较之前将bool转换为int.@H_502_5@
Do you kNow any case where this corner case might become a real issue? (For example while binary loading of data from a stream)
这是一个真正的问题.@H_502_5@
Is this okay?@H_502_5@
I don’t kNow whether the specs specify anything about this. A compiler might always create a code like this: ((a!=0) && (b!=0)) || ((a==0) && (b==0)) when comparing two booleans,although this might decrease performance.@H_502_5@
In my opinion this is not a BUG,but an undefined behavIoUr. Although I think that every implementor should tell the users how boolean comparisons are made in their implementation.@H_502_5@
如果我们去最后一个代码示例,那么a和b都是bool,并且通过分配1和2来设置为true(否则1和2消失,它们现在只是真的).@H_502_5@
所以打破你的表情:@H_502_5@
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
所以我总是期望上面的表达式得到很好的定义,并且始终是真实的.@H_502_5@
但我不知道这是如何适用于您的原始问题.当将一个整数分配给bool时,整数将转换为bool(如上所述). true的实际表示不是由标准定义的,可以是适合bool的任何位模式(您不能假定任何特定的位模式).@H_502_5@
当将bool与int进行比较时,将bool转换为int,然后进行比较.@H_502_5@
Any real-world case@H_502_5@
The only thing that pops in my mind,if someone reads binary data from a file into a struct,that have bool members. The problem might rise,if the file was made with an other program that has written 2 instead of 1 into the place of the bool (maybe because it was written in another programming language).@H_502_5@
But this might mean bad programming practice.@H_502_5@
以二进制格式编写数据是不可知的.
每个对象的大小都有问题.
有代表性的问题:@H_502_5@
>整数(有endianess)
> float(表示未定义(通常取决于底层硬件))
Bool(二进制表示法未定义)
>结构(成员之间的填充可能不同)@H_502_5@
所有这些您需要知道底层硬件和编译器.编译器的不同编译器或不同版本的编译器,甚至具有不同优化标记的编译器可能对上述所有 *** 作都有不同的行为.@H_502_5@
联盟的问题@H_502_5@
struct X{ int a; bool b;};
当人们提到写“a”,然后从’b’读取是未定义的.
为什么:因为我们不知道在这个硬件上如何表示’a’或’b’.写入’a’将填写’a’中的位,但如何反映在’b’中的位.如果您的系统使用1字节布尔和4字节整数,低位存储器中的最低字节为最低字节,则将1写入’a’将1置于’b’.但那么你的实现如何代表一个bool?是真的表示1或255?如果将1置入’b’,并且真正使用255的所有其他用途会发生什么?@H_502_5@
所以除非你了解你的硬件和你的编译器的行为将是意想不到的.@H_502_5@
因此,这些用途是未定义的,但不被标准所禁止.他们被允许的原因是你可能已经做了这个研究,发现在你的系统上使用这个特定的编译器,你可以做一些自由的优化,做出这些假设.但是请注意,假设中的任何更改将会破坏您的代码.@H_502_5@
另外当比较两种类型时,编译器将在比较之前进行一些自动转换,请记住在比较之前将两种类型转换为相同类型.为了在整数和bool之间进行比较,将bool转换为整数,然后与另一个整数进行比较(转换将false转换为0,并将其转换为1).如果要转换的对象都是bool,那么不需要转换,并且使用布尔逻辑进行比较.@H_502_5@ 总结
以上是内存溢出为你收集整理的奇怪的C布尔铸造行为(true!= true)全部内容,希望文章能够帮你解决奇怪的C布尔铸造行为(true!= true)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)