微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 在for循环中重新排序测试条件:编译器错误?

我有一个存储在数组中的树,我正在尝试找到一个特定的节点:
std::vector<Node> nodes = ...
const unsigned short sentinel = -1;
unsigned short index = 0;
for (Node* node = &nodes[index]; // root node
     index != sentinel;
     node = &nodes[index])
{
    if (foo(*node)) {
       index = node->left;
    } else {
       index = node->right;
    }
}

换句话说,没什么特别的.但是,MSVC 2012失败,尝试访问超出范围的节点[sentinel].事实证明,它首先计算& nodes [index],然后测试索引. (调试模式,无优化).

对我来说,这看起来像代码生成错误,但我至少在十年内没有看到过这样的错误.这是简单的未经优化的代码.当然,即使重新排列,在测试索引之前实际上并未使用节点,并且在x86上具有这样的越界指针并不是非常不安全,但是MSVC的向量<>合法地断言该非法指数.

干净的构造并再次检查组件;它是可重复的.树也不是空的,总是有一个根节点.

我忽略了什么,或者这真的是一个严重的编译器错误

解决方法

你的代码重写为while循环就像
Node* node = &nodes[index]; // root node
while(index != sentinel)
{
    {
        if (foo(*node)) {
           index = node->left;
        } else {
           index = node->right;
        }
    }

    node = &nodes[index];
}

最后一行可能是对节点[-1]的访问.

我会把你的循环改写成

unsigned short index = 0;
do
{
    Node* node = &nodes[index];
    if (foo(*node)) {
       index = node->left;
    } else {
       index = node->right;
    }
} while(index != sentinel);

原文地址:https://www.jb51.cc/c/119060.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐