【问题标题】:C++ comparison operator not returning true or falseC ++比较运算符不返回真或假
【发布时间】:2014-12-15 09:51:41
【问题描述】:

我有以下程序

int a = 216;
bool* v = (bool*)((void*)&a);
std::cout << (*v == true) << endl;

我希望这个程序打印出 true 或 false,但它打印出 216。我用g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2 编译了它。是预期的行为还是一些错误?为什么相等运算符会返回与 bool 不同的类型?

--------- 编辑 ---------

我的意图不是强制转换为 void,而是让 v 将 216 存储在其内存位置。替代程序可能如下所示:

bool v;
int a = 216;
memcpy(&v, &a, sizeof(bool));
std::cout << (v == true) << endl;

或者我可以采用未初始化的布尔指针,它指向某个随机值,例如216.

【问题讨论】:

  • v 指向一个临时的(由所有演员表创建),该临时文件在创建它的行的末尾是无效的。也许让v 成为bool 而不是bool*。请记住,v 将始终为真,这里它指向有效的内存位置(a 的地址)。试试bool v = (&amp;a);
  • Cannot reproduce。我在stdout 中没有看到216。
  • @Cyber​​ 你确实看到了0 而不是预期的1。 UB 万岁!
  • 由于 p 实际上并不像您说的那样指向 bool,因此代码未定义,216 是一个完全合理的结果。 (输出为 216,因为如果 p 是 bool*,则可以将 *p == true 替换为 *p 并且编译器会这样做。)

标签: c++ operators logical-operators compiler-bug


【解决方案1】:

在将指针转换为void* 后,唯一有效的方法是将其转换回原始指针类型(在您的情况下为int*)。不过,您将其转换为 bool*,这会将您带入 未定义行为 的领域。或者,换句话说,你不能期望任何事情都会以某种方式发生。

您可能认为去掉void* 的演员可以解决这个问题。但是,在将指针转换为不同的指针类型后取消引用也会导致未定义的行为。

虽然这样可以很容易地实现预期的输出:

bool v = (bool) a;
std::cout << (v == true) << std::endl;

【讨论】:

  • 强制转换为 void 只是为了指向其中包含 216 的某个内存位置。您可以尝试通过不同的方式来做到这一点,例如您可以将 216 写入为 bool 保留的内存位置。结果是一样的。
  • @Trismegistos :听起来您通过将bool* 转换为int* 然后取消引用int* 来设置值,从而将整数值写入bool 变量。如果是这样,请检查我的答案的第二段 - 这也会导致未定义的行为。
  • @Trismegistos :从更新到您的问题,您似乎使用了 memcpy 和两种不同的指针类型。这又是未定义的行为,原因基本相同:您试图将int 值视为bool 值。不要试图规避类型安全 - 不会有任何好处。
  • 我从第三方目录得到这样的结果,我怀疑发生的情况是创建了类(在堆上的堆栈上没关系)并且某些字段未初始化然后在某些时候我得到一个 bool 字段使用 getter 并将其与 true 进行比较。那还是UB吗?
  • @Trismegistos :我认为你需要花一些时间来弄清楚你想问的真正问题是什么。您似乎不断添加更多信息,这些信息显着改变了问题,这让我们很难跟上。一旦你弄清楚你想问什么,你就可以把它当作一个新问题来问。
【解决方案2】:
int a = 216;
bool* v = (bool*)((void*)&a);
std::cout << (*v == true) << endl;

a = 216 = 128+64+16+8 = 00000...11011000

*v = 1000 如果我们打印它,它会显示为 true...

但是 true=0001 并且不满足 *v==true

当然这是我实验后的猜测......

感谢你之后我总是使用 something!=false 而不是 something== true...

or something==false 而不是 something!=true...

【讨论】:

    猜你喜欢
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2015-12-28
    • 2014-09-07
    • 1970-01-01
    相关资源
    最近更新 更多