for循环中的奇怪行为-bug? 我在Windows 7机器上使用VisualStudio 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; } }
当我用硬编码的1替换常量unsigned int k时,它也可以工作:for循环中的奇怪行为-bug? 我在Windows 7机器上使用VisualStudio 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; } },c++,visual-studio-2012,compiler-construction,C++,Visual Studio 2012,Compiler Construction,当我用硬编码的1替换常量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
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;
}
}
void loopTest3()
{
//常数无符号整数k=1;
对于(int m=0;m您的int m
将被提升为无符号int
。在第一个循环中,这意味着m-k
作为无符号值等于-1,这是最大无符号值,明显大于m+k
(当比较n
时,它将被提升)。从另一个角度来看,您将得到n
是-1的无符号表示,m+k
是1。当然,当您将-1无符号存储到有符号整数中时,它会溢出,并且在技术上是未定义的行为。它很可能保留其-1表示,然后被提升回最大无符号值。
以下是第一次迭代的总结:
迭代1:
m:0
k:1u
n=m-k:-1u=max uint,存储到签名整数中
m+k:1u
n max uint您可以尝试检查反汇编以查看发出的代码。编译器可能会发出一个关于无符号/有符号不匹配的警告,因为您从有符号整数m中减去了无符号整数k-可能已经解决了这个问题。@Niko,应该是的。Niko,我刚刚用int k=1
对它进行了测试,结果是正确的ked!你能在回答中重复你的评论吗?在函数开头设置一个断点,一旦它被点击,调用Debug->Windows->DisassemblySo,我就必须写int n=m-static\u cast(k)
在for循环中,如果我想保持k不带符号,对吗?@Ben,如果你想保持第一,这似乎是最好的选择,但你也需要n是的,我也意识到了。谢谢你的回答!我根本没有看到这个问题,因为我希望k
被提升为int
@本,如果你不预测,C++中的促销和标准算术转换会很难咬。STL实际上有一个视频讨论了从MSVC中出现的bug。它是核心C++系列中的视频7。
acc: 2
acc: 3
acc: 2
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;
}
}