ise*_*sky 1 c++ visual-studio-2010
所以我只是遇到了前缀运算符.
在我的Visual C++ 2010中的调试版本中.
someArray[++index]
Run Code Online (Sandbox Code Playgroud)
将正确递增数组索引,然后使用它索引到数组.
在我的发布版本中,它使用了数组索引,然后在之后递增,导致一些巨大的麻烦.
奇怪的是我的调试构建代码实际上有一段时间是错误的,我把它写成了
someArray[index++]
Run Code Online (Sandbox Code Playgroud)
这将使用索引然后递增它,但调试版本仍在递增它,然后使用该值.直到今天早上我才意识到自己的错误.
这是实际代码的示例.
for(unsigned int newPointIndex = 0; newPointIndex < newEdgeList.size() - 1;) {
m_edges.push_back(Edge(newEdgeList[newPointIndex], newEdgeList[++newPointIndex]));
}
Run Code Online (Sandbox Code Playgroud)
for循环中没有增量发生.当我索引到数组中时,它发生在循环内部的实际代码中.我认为这是一个聪明的小优化,但它使它在发布版本中不起作用.
我第二次索引到数组时,它在发布版本中使用了未增加的索引,但是在调试版本中工作.
你的for循环体包括:
Edge(newEdgeList[newPointIndex], newEdgeList[++newPointIndex])
Run Code Online (Sandbox Code Playgroud)
这是不确定 不确定不确定[1]的行为,因为这两个参数可以以任何顺序(或者甚至同时)进行评估,因此目前还不清楚是否newPointIndex会被增加或没有在第一次使用前.
调试和优化的构建很可能以不同的顺序评估参数.
我建议将newPointIndex增量放在for语句本身,并写入正文:
Edge(newEdgeList[newPointIndex], newEdgeList[newPointIndex + 1])
Run Code Online (Sandbox Code Playgroud)
[1]:阅读关于un {specified,defined}讨论的评论.tl;博士:神圣的飞跃蜥蜴,蝙蝠侠!
该问题实际上是在这里:
m_edges.push_back(Edge(newEdgeList[newPointIndex], newEdgeList[++newPointIndex]));
Run Code Online (Sandbox Code Playgroud)
您无法分辨这两个表达式中的哪一个newEdgeList[newPointIndex]并且newEdgeList[++newPointIndex]将首先执行.
根据C++标准,无法保证它们将从左到右执行.见5.2.2/8:
"后缀表达式和参数表达式的评估都是相对于彼此无法排序的.参数表达式评估的所有副作用在输入函数之前都会被排序"
相关的是1.9/15:
"当调用函数时(无论函数是否为内联函数),在执行每个表达式或语句之前,对任何参数表达式或指定被调用函数的后缀表达式相关联的每个值计算和副作用都会被排序.被调用的函数.[注意:与不同的参数表达式相关的值计算和副作用是未被排序的.-end note]"
这意味着一个实现不仅可以在调试中使用不同的执行顺序来释放构建,而且理论上也可以在每次在同一程序执行中执行该语句时以非确定的方式更改顺序.
该解决方案包括采取增量掉那些子表达式(如在另一个答案指出).
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |