增量已优化(Visual C Express 2010)
Increment optimized away (Visual C Express 2010)
在使用Visual C++Express 2010进行C++项目时,我发现了一个我想了解的有趣问题。问题是,如果我在调试或发布模式下编译,我的程序的结果会有所不同。我制作了一个小程序来复制它:
#include <stdio.h>
int firstarg(int i)
{
printf("First argument called with i = %dn", i);
return i;
}
int secondarg(int i)
{
printf("Second argument called with i = %dn", i);
return i;
}
void function(int i, int j)
{
printf("Function called with %d, %dn", i,j);
}
int main(int argc, char* argv[])
{
// Line with the problem!
for (int i = 0; i < 5; ) function(firstarg(i), secondarg(i++));
return 0;
}
// Result on RELEASE:
Second argument called with i = 0
First argument called with i = 0
Function called with 0, 0
Second argument called with i = 1
First argument called with i = 1
Function called with 1, 1
Second argument called with i = 2
First argument called with i = 2
Function called with 2, 2
Second argument called with i = 3
First argument called with i = 3
Function called with 3, 3
Second argument called with i = 4
First argument called with i = 4
Function called with 4, 4
// Result on DEBUG
Second argument called with i = 0
First argument called with i = 1
Function called with 1, 0
Second argument called with i = 1
First argument called with i = 2
Function called with 2, 1
Second argument called with i = 2
First argument called with i = 3
Function called with 3, 2
Second argument called with i = 3
First argument called with i = 4
Function called with 4, 3
Second argument called with i = 4
First argument called with i = 5
Function called with 5, 4
正如您所看到的,在这两种情况下,第二个参数都是在第一个参数之前求值的(如果参数是在某种后进先出堆栈中处理的,那么我所期望的那个参数);但在释放中,变量i的增量被"优化掉",并被延迟到循环的下一次迭代。这是出乎意料的,我真的很想了解发生了什么。
当然,我可以通过将循环更改为来轻松地"修复"我的代码
for (int i = 0; i < 5; ++i) function(firstarg(i+1), secondarg(i));
不管编译参数如何,这将总是给出相同的结果。但是,我仍然想了解这种增量优化背后的原因。
PS。顺便说一句,我无法在linux下用gcc重现这个问题(使用-O0标志调试,使用-O3发布)。
您误解了结果。增量不会被"优化掉"或延迟到循环的下一次迭代。在下一次迭代之前,您无法查看i
的值是多少。试试这个:
for (int i = 0; i < 5; )
{
function(firstarg(i), secondarg(i++));
printf("At end of iteration, i = %dn");
}
你会发现它一点也没有延迟。
您的代码是UB,因为您可以访问一个变量并修改同一个变量,而不需要插入序列点。虽然你可能会得到非常疯狂的结果,但实际上你会得到两个"预期"的结果,这取决于你的优化。函数参数的求值顺序未指定。
您的程序在没有插入序列点的情况下(在function
的函数调用表达式中)修改并读取变量i
两次,这只是未定义的行为。
我认为您有一个序列点导致未定义行为的问题:
-
这是一个类似的问题:为什么这些构造(使用++)是未定义的行为?
-
这个答案很好:为什么这些构造(使用++)是未定义的行为?
-
http://en.wikipedia.org/wiki/Sequence_point
在任何情况下,解决方案都是不编写这种代码。
- C++ Visual Studio Express 2010 無法啟動程式錯誤
- Visual C++express 2010程序入口点??1task_group_context@tbb@@QAE@XZ
- 链接到 libpq 并将其与 Visual C++ Express 2010 一起使用
- PThreads for visual studio express 2010
- 增量已优化(Visual C Express 2010)
- Visual Studio Express 2010 C++中的重构
- 在 Visual Studios Express 2010 上设置根库
- TortoiseSVN and Visual Studio Express 2010
- 在 Visual C++ Express 2010 中找不到.exe文件
- VC++ Express 2010 在模板化类的重载赋值运算符的自赋值测试中出错
- 如何在visual C++express 2010中编译此逻辑
- 在Visual C++Express 2010中从串行端口读取
- 如何将项目从Visual C++6.0转换为Visual Studio Express 2010
- Visual Studio Express 2010 C++反汇编调试
- 使用Visual c++ Express 2010 IDE编译和使用cl命令在控制台下编译时,exe大小不同
- Directshow vc++ express 2010 vs图形编辑
- 在visual express 2010中使用std::copy出现错误
- 我似乎无法得到Visual c++ Express(2010)来识别枚举类
- Visual Studios Professional 2013 是 C++ 的新增功能,无法运行在 Visual Studios C++ Express 2010 中制作的项目
- Visual c++ express 2010高亮显示