Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何确定长函数返回的位置_C++_C_Return - Fatal编程技术网

C++ 如何确定长函数返回的位置

C++ 如何确定长函数返回的位置,c++,c,return,C++,C,Return,假设有一个名为LongFunction的1000行代码的函数,我们使用它: bool bSuccess = LongFunction(); assert(bSuccess); 这里我在调试时得到了一个断言,我知道LongFunction有问题,所以我需要找到函数在哪里遇到问题并返回: 我可能可以一步一步地调试它,它可以工作,但很耗时,我们不知道如何用这种方式进行调试 我可以搜索关键字“return”(或者更精细的搜索使用RegExp),并在这些返回处设置断点,应该会更快,但这仍然是繁琐的手工工

假设有一个名为LongFunction的1000行代码的函数,我们使用它:

bool bSuccess = LongFunction();
assert(bSuccess);
这里我在调试时得到了一个断言,我知道LongFunction有问题,所以我需要找到函数在哪里遇到问题并返回:


  • 我可能可以一步一步地调试它,它可以工作,但很耗时,我们不知道如何用这种方式进行调试

  • 我可以搜索关键字“return”(或者更精细的搜索使用RegExp),并在这些返回处设置断点,应该会更快,但这仍然是繁琐的手工工作,无法自动完成

  • #定义返回跟踪();返回

  • 它可以工作,但存在以下问题:

    • 由于经常使用return,它将打印太多的冗余信息。(或者我们可以使用一些EnvVar来打开或关闭它)
    • 不适用于以下情况:if(bOK)返回true
    对于如何找出问题,你还有其他创造性的想法吗

    编辑: 下面是一些细节,让我们关注这个问题

    <> >是C++,不是平台Spfic。

  • 我们不想重构函数(是的,我知道我们应该),我们甚至不想更改任何代码——在这一点上,我们只想提供一些工具,使我们的应用程序调试更容易。我也相信这应该是一个共同的要求,你没有遇到过吗

  • LongFunction()有多个退出点,返回类型不是NECTORSOOL(HRESULT,用户定义的错误代码…)

  • 编辑:当前讨论的摘要:
    我们有一些争议:

  • 您应该重构函数。
    是的,每个人都知道我们应该这样做,但这不是重点。如果我打电话重构函数,我不会在这里问这个问题

  • 查找LongFunction()返回失败的位置没有帮助。
    我要做的第一件事就是找到错误发生的地方,然后知道发生了什么,我很好奇为什么这样做没有帮助,在这种情况下你做了什么?(假设我已经熟悉该函数的工作原理)

  • 我们有两个合理的解决方案:

  • 来自Crashworks的ReturnMarker,函数中的堆栈对象将在函数返回时销毁,在析构函数处设置断点将显示它在调试程序中返回的位置

  • CMyBool(x)来自Binary&Sadsido,将LongFunction的返回类型更改为CMyBool,它可以从bool进行构造,从LongFunction返回将构造该对象,因此只需在构造函数处设置断点即可


  • 听起来是时候重构LongFunction()

    1000行函数是一种糟糕的代码味道。花时间将其重构为更小、更易于维护的功能。你会发现错误,而你在它(的),这将是一个值得投资的未来

    #define return { TRACE(LINE); return; }
    
    这就解决了你的问题

    至于其他方面,这只是编码的问题。这就是为什么许多系统在出现问题时会返回更复杂的错误(例如来自COM对象的HRESULT)和/或向调试流发送垃圾邮件

    不过,应重新演示1000行函数。正如您所看到的,一个很长的函数很难维护

    编辑:下面的工作会比上面的更好吗

    #define return TRACE(LINE), return
    
    喝了几杯,所以可能不好。

    < P>这是C还是C++?< /P>

    如果C++,创建一个包BoOL(比如CyMBOOL)的新类,它有一个自动转换成BoOL。 现在使用LongFunction return CMyBool(快速搜索和替换会将LongFuntion中的所有返回更改为“return CMyBool(x)”

    现在在CMyBool的ctor中放置一个断点,当创建CMyBool时,调试器将停止,它将位于LongFunction中正确的return语句中

    自动转换为bool将阻止CMyBool破坏使用CMyBool的代码

    这将使您克服最初的问题,但更大的问题是需要重构LongFunction


    希望这能有所帮助。

    如果你的问题仅仅是懒惰(顺便说一句,这没什么错),请确保LongFunction中的所有返回语句的格式都相同

    return(value);
    
    而不是

    return value;
    
    (例如,使用正则表达式搜索和替换)

    然后,使用一个比您最初建议的略为修改的预处理器宏:

    #define return(value) { if (!value) TRACE(__LINE__); return(value); }
    
    …甚至

    #define return(value) { assert(value); return(value); }
    

    …或您认为合适的任何内容

    您尚未说明您的平台。根据
    LongFunction
    的内容,以下是我使用gdb的方法:

    假设您的文件“f.cc”有以下几行:

    1: bool LongFunction () {  /* ... */ }
    2:
    3: void bar ()
    4: {
    5:   bool bSuccess = LongFunction ();
    6:   assert (bSuccess);
    7: }
    
    以下是gdb中的步骤:

  • 在与断言相同的行上添加断点:
    break f.cc:6

  • 为bSuccess为false时的断点添加一个条件:
    条件1(bSuccess==0)

  • 运行程序,直到达到该断点

  • 在函数体的开头设置断点:
    break f.cc:4

  • 跳回该位置(它将在断点处停止):
    Jump f.cc:4

  • 调试LongFunction的内容以了解其失败的原因

  • 我之所以说这取决于LongFunction的内容,是因为如果长函数读取流中的输入,或者修改全局变量等,那么第二轮的行为可能不同。

    3: void bar ()
    4: {
    5:   bool bSuccess = LongFunction ();
    5:   bSuccess = LongFunction ();
    6:   assert (bSuccess);
    7: }
    

    VisualStudio我会在断言上放置断点,然后使用堆栈跟踪窗口点击下一行,然后将你带到方法的退出点。

    显然你应该重构这个函数,但是C++中你可以用这个简单的权宜之计在五分钟内处理这个问题:

    class ReturnMarker
    {
       public:
       ReturnMarker()  {};
       ~ReturnMarker() 
       {
          dummy += 1; //<-- put your breakpoint here
       }
       static int dummy;
    }
    
    int ReturnMarker::dummy = 0;
    
    “我可能可以一步一步地调试它,它可以工作,但很耗时,我们不知道
    void LongFunction()
    {
        ReturnMarker foo;
    
        // ...
    }