c++ - for 循环中的奇怪行为 - 一个错误?

标签 c++ visual-studio-2012 compiler-construction

我在 Windows 7 机器上使用 Visual Studio 2012,当尝试运行以下代码片段(使用 x64 模式下的默认 VC11 C++ 编译器编译)时,断言失败,这意味着内部循环永远不会输入:

void loopTest1()
{
    const unsigned int k = 1;

    for (int m=0; m<3; ++m)
    {
        int acc = 0;

        for (int n=m-k; n<=m+k; ++n)
        {
            if (n<0 || n>=3) continue;

            ++acc;
        }

        assert (acc>0);

        cout << "acc: " << acc << endl;
    }
}

现在我改变内循环的结束条件:

void loopTest2()
{
    const unsigned int k = 1;

    for (int m=0; m<3; ++m)
    {
        int acc = 0;

        int l = m+k; // this line was added
        for (int n=m-k; n<=l; ++n) // m+k was replaced by l
        {
            if (n<0 || n>=3) continue;

            ++acc;
        }

        assert (acc>0);

        cout << "acc: " << acc << endl;
    }
}

然后我得到正确的结果:

acc: 2
acc: 3
acc: 2

当我用硬编码的 1 替换 const unsigned int k 时,它也可以工作:

void loopTest3()
{
    //const unsigned int k = 1;

    for (int m=0; m<3; ++m)
    {
        int acc = 0;

        for (int n=m-1; n<=m+1; ++n) //replaced k with 1
        {
            if (n<0 || n>=3) continue;

            ++acc;
        }

        assert (acc>0);

        cout << "acc: " << acc << endl;
    }
}

编译器是否执行了一些错误的优化? 或者有什么具体原因,为什么第一种情况的行为至少是出乎意料的?

最佳答案

您的 int m 将被提升为 unsigned int。在第一个循环中,这意味着 m-k 等于 -1 作为无符号值,这是最大的无符号值并且明显大于 m+k(当 n 进行比较,它得到提升)。从长远来看,您最终会得到 n 是 -1 的无符号表示,而 m+k 是 1。当然,当您存储 -1 无符号时变成有符号整数,它会溢出并且在技术上是未定义的行为。它最有可能保持其 -1 表示,然后被提升回最大无符号值。

以下是第一次迭代的总结:

Iteration 1:
m: 0
k: 1u
n=m-k: -1u = max uint, stored into signed int
m+k: 1u
n<=m+k --> max uint <= 1u

在您的第二个示例中,n 与另一个有符号整数进行比较时不会提升,它会比较两个有符号整数。在你的第三个中,没有什么是未签名的。

关于c++ - for 循环中的奇怪行为 - 一个错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16736141/

相关文章:

c++ - 从子类c++调用基类方法

database - 如何使用 localdb 在 Code First 中查看数据库图表

c# - .net 中的 IL 和堆栈实现?

c++ - 基于另一个模板对象创建模板对象

c++ - 我试图通过 espeak 传递一些字符串,它会读取它们,但我得到 "segmentation fault"

c++ - 二叉搜索树中的最低公共(public)祖先

c# - VS调试器为什么不停止在初始化变量上?

visual-studio - Visual Studio - 在文件中查找 > 不是任何 node_modules 文件夹

java - 如何使用 .jar 库编译 Java 程序

xcode - 在 Mac OSX 10.6.8 上安装 f2c