【问题标题】:Why the executable produced in "release " mode gives a bad result?为什么在“发布”模式下生成的可执行文件会产生不好的结果?
【发布时间】:2023-04-04 07:21:01
【问题描述】:
#include <iostream>


int maxComDiv(int mayor, int menor)
{
    int resto = mayor % menor;
    if (resto > 0) maxComDiv(menor, resto);
    else return menor;
}

int main()
{
    std::cout << "max comon divisor: " << maxComDiv(3654, 1365) << std::endl;
}

使用 Visual Studio 2015 社区更新 2 --> 在发布模式下失败。好在调试模式。 使用 mingw64 --> 在两种模式下都很好。

【问题讨论】:

  • 如果条件resto &gt; 0为真,函数返回什么?
  • @JimmyB bad results 似乎表明程序给出了结果,这意味着编译成功,那么我的问题是:编译成功后,不同的警告级别会导致不同的输出代码吗?
  • “失败”不是可接受的问题描述。
  • 告诉我们您所说的“失败”是什么意思。每种情况下可执行文件的输出是什么?
  • 如果我表达不正确,我深表歉意。我英语说得不好。当我说可执行文件失败时,意味着不会产生正确的结果。在这种情况下,正确的结果是 21。vs2015-release mode: result is random。

标签: c++ visual-studio


【解决方案1】:

程序的行为是未定义,因为macComDivreturn在所有控制路径上都定义。

我想你是想写if (resto &gt; 0) return maxComDiv(menor, resto);

(在 C++ 中没有隐式返回值)。

这说明了调试版本和发布版本之间的差异。

【讨论】:

  • 我要补充一点:首先要检查您的程序何时在调试中运行良好但在发布中运行不正常是undefined behaviour
【解决方案2】:

您应该阅读警告消息,使用 gcc 您会得到:

prog.cc: In function 'int maxComDiv(int, int)':
prog.cc:11:1: warning: control reaches end of non-void function [-Wreturn-type]
 }

表示缺少返回语句:

if (resto > 0) 
    return maxComDiv(menor, resto);
    ^^^^^^ ~~~~~~~~ !!

这会导致未定义的行为

【讨论】:

    【解决方案3】:

    问题在于,当您启用发布模式时,C++ 编译器会尝试优化您的代码以使其尽可能快地运行。

    此外,它无法理解if(resto&gt;0) 会调用递归方法并最终返回 false。

    由于它发现并非您的方法中的所有代码路径都返回一个值(if(resto&gt;0) 不返回一个值),所以它给了您错误。

    【讨论】:

    • “最终会返回 false”?!
    • 由于它会在方法调用中继续使用余数,最终if(resto &gt; 0) 将返回false,因为resto 将为0。
    • 好的,你的意思是 comparison 产生false,而不是递归方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多