visual-c – 用循环优化VC 2015除以零

visual-c – 用循环优化VC 2015除以零,第1张

概述史前史: 我们刚刚从VC 2008开始将我们的开发环境转换为VC 2015.在此之后我们发现了问题:尽管在C代码中测试了分隔符,程序仍然将0除以0. 测试代码: #include <cstdlib>int test(int n, int test_for_zero){ int result = 0; for (int i = 0; i < n; ++i) { 史前史:

我们刚刚从VC 2008开始将我们的开发环境转换为VC 2015.在此之后我们发现了问题:尽管在C代码中测试了分隔符,程序仍然将0除以0.

测试代码:

#include <cstdlib>int test(int n,int test_for_zero){    int result = 0;    for (int i = 0; i < n; ++i) {        if (test_for_zero)            result += rand() >> ((8 % test_for_zero) * test_for_zero);    }    return result;}int main(){    return test(rand(),rand() & 0x80000000);}

由VC 2015 Update 3或VC 2017编译并使用默认的Release选项,在运行时它将除以零.由VC 2008编译运行得很好.

分析:

; 6    :    for (int i = 0; i < n; ++i) {    test    edi,edi    jle SHORT $LN15@main; 7    : ; 8    :        if (test_for_zero); 9    :            result += rand() >> ((8 % test_for_zero) * test_for_zero);    mov ecx,DWORD PTR _test_for_zero$[ebp]    mov eax,8    cdq    idiv    ecx  ; <== IT'S HERE,Idiv BEFORE CHECKING FOR ZERO    mov eax,edx    imul    eax,ecx    mov DWORD PTR tv147[ebp],eax    test    ecx,ecx    je  SHORT $LN15@main$LL11@main:    call    ebx    mov ecx,DWORD PTR tv147[ebp]    sar eax,cl    add esi,eax    sub edi,1    jne SHORT $LL11@main

编译器从循环体中获取常量部分((8%test_for_zero)* test_for_zero)并且忘记在分割之前测试test_for_zero.显然,只需通过编译器作业即可正确地修复它.

我玩了几个编译器选项,比如-d2SSAOptimizer-和-Oxx,但解决这个问题的唯一选择是-Od.

问题:

>这是一个错误吗?自VC 2008以来,C标准发生了很大变化,所以可能会受到这样的影响吗?
>主要问题是,除了-Ob之外,是否有通过编译器选项解决问题的解决方法?

解决方法 感谢您的报告和小型repro(特别是Visual Studio中的反馈!),它们非常有助于隔离问题.

这确实是编译器本身的一个错误,特别是“Invariant Code Motion”优化过程中的安全检查.我已经解决了这个问题,它应该出现在VS 15.7中.

目前,最简单的解决方法是通过https://docs.microsoft.com/en-us/cpp/preprocessor/optimize禁用具有此代码模式的函数的优化:

#pragma optimize( "",off )      <Function containing code with this loop>    #pragma optimize( "",on )

不幸的是,这个优化过程直接与优化器绑定,因此除了完全禁用优化器(-Od)之外没有编译器选项可以解决这个问题.

总结

以上是内存溢出为你收集整理的visual-c – 用循环优化VC 2015除以零全部内容,希望文章能够帮你解决visual-c – 用循环优化VC 2015除以零所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1229019.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存