【问题标题】:Integer not comparing equal to its value整数不比较等于它的值
【发布时间】:2015-04-29 21:05:15
【问题描述】:

我有一段代码正在尝试调试,这会产生奇怪的结果。一个非常清楚地包含值 6 的整数将 false 与文字 6 进行比较。
在我的代码中,这段代码:

int allGreen = 0;
int index = 0;
while (ch->fb[index]->selection_color() == FL_GREEN) 
{
    ++allGreen;
    ++index;
}
std::cout << allGreen << std::endl;
std::cout << std::boolalpha << (allGreen == 6) << std::endl;

产生输出:

6
false

我在 Ubuntu 上使用 g++ 4.8.2 进行编译。

这怎么可能发生?

编辑:从条件中删除所有绿色无济于事。 编辑 2: index 和 allGreen 是相等的,正如预期的那样。两者都不等于 6,尽管两者都是 6。

【问题讨论】:

  • 我们可以有“一些条件”,以便我们自己运行这段代码
  • 抱歉,有些条件不是很有帮助,因为它与代码库的其余部分紧密集成。
  • 某些条件是“ch->fb[allGreen]->selection_color() == FL_GREEN”
  • 除了“某些条件”之外的所有内容都是实际代码吗?
  • 请提供MCVE

标签: c++ int comparison-operators


【解决方案1】:

ch-&gt;fb 数组的大小是多少?如果是 6 或更少,则可能是编译器在此处优化未定义的行为。

当看到一些简单的循环时

while ( a[i] ) i++;

编译器可以假设i 永远不会超出a 数组,否则程序会调用未定义的行为。即i 介于0size of a - 1 之间。

稍后,如果编译器看到类似i == 8 的东西,则8 大于size of a - 1,它会将这个条件替换为false

为了确定,您可以查看汇编代码。

【讨论】:

  • ch->fb的大小为6。
  • 然后我将扩展我的答案以显示发生了什么
  • 看来您对问题的看法是正确的。将大小更改为 7 可以解决问题。我注意到它在数组的末尾运行(我没有编写代码),但我认为这并不重要,因为我得到了数字 6。我很想知道为什么这会破坏比较。
  • 这很有趣。确实有道理。
  • @Patrick 正如一位睿智的中国老僧所说,“未定义的行为是未定义的”。说真的,看看this excellent llvm blog post,了解为什么一旦 UB 进入它就会发生任何事情,以及编译器如何甚至不知道 UB 大部分时间都在发生。
【解决方案2】:

字面量“6”不是整数,也没有值 6。

【讨论】:

  • 我没有在代码中使用单引号。我想我的措辞很糟糕。
【解决方案3】:

正如 deniss 已经指出的那样,越界访问数组是未定义的行为,所以也许这就是原因。确保也检查数组的边界。

因此,如果可以计算数组的每个 selection_color,您可以尝试:

const int MAX_FB_VALUES = 6;

// ...

int countOfGreen = 0;

for (int i = 0; i < MAX_FB_VALUES; ++i)
{
    if(ch->fb[i]->selection_color() == FL_GREEN)
        ++countOfGreen;
}

std::cout << countOfGreen << std::endl;
std::cout << std::boolalpha << (countOfGreen == MAX_FB_VALUES) << std::endl;

当然,尽管使用容器会更好。

【讨论】:

  • 谢谢。我没有意识到越界可能会破坏未来的比较,所以我并不担心那部分代码。我当然会使用一个容器,但是这个代码是在这种状态下给我的。了解这如何打破 6 和 6 之间的比较会很有趣。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
相关资源
最近更新 更多