Visual C++ 2017疑似Bug?编译器优化消除表达式问题
问题分析与解答
嘿,我来帮你拆解这个问题~
首先明确:你的代码不存在语法格式错误,但存在设计上的语义问题,进而在激进编译优化下触发了不符合预期的行为。
为什么特定优化组合下diff始终为0?
你的数组类原本的operator[]返回的是T(值类型),而不是引用。当你计算两个数组元素的差值时,每次调用operator[]都会生成一个临时对象(数组元素的拷贝)。
在开启/O1//O2//Ox(全局优化)+ /Ob2(内联所有可行函数)+ /Ot(优先速度优化)的组合下,编译器会做非常激进的优化:它可能会判定两次调用operator[]生成的临时对象是“等价且无副作用”的,进而复用同一个临时对象的数值——这就导致a[i] - b[i]实际上变成了同一个临时值减自身,结果自然是0。
为什么改成const T&就解决了问题?
当operator[]返回const T&时,你直接引用数组容器里存储的实际元素,不再生成临时拷贝。编译器能清晰识别到你是在访问两个不同数组的独立元素,不会触发上述的误优化,计算结果也就符合预期了。
额外提醒
这种返回值类型的operator[]设计本身就不符合C++容器的常规规范:容器的operator[]几乎都会返回引用(T&或const T&),不仅能避免不必要的拷贝开销,还能规避这类因临时对象引发的优化陷阱。你的修复方案是完全正确的。
内容的提问来源于stack exchange,提问作者lightxbulb
相关产品推荐
相关产品推荐

