c/c++语言开发共享如何确定long函数返回的位置

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

bool bSuccess = LongFunction(); assert(bSuccess); 

这里我在调试时得到一个断言,我知道LongFunction有问题,所以我需要找到函数遇到问题的地方并返回:

它有效,但有以下问题:

您对如何查明问题还有其他创意吗?

编辑:以下是一些让我们关注问题的细节。

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

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

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

     class ReturnMarker { public: ReturnMarker() {}; ~ReturnMarker() { dummy += 1; //<-- put your breakpoint here } static int dummy; } int ReturnMarker::dummy = 0; 

    然后在函数顶部实例化一个ReturnMarker。 当它返回时,该实例将超出范围,您将点击析构函数。

     void LongFunction() { ReturnMarker foo; // ... } 

    听起来好像是重构LongFunction()的时候了……

    一个1000行function是一个坏代码气味。 花时间将其重构为更小,更易维护的function。 您可以在遇到错误时找到错误,这对未来将是一次值得的投资。

    这是C还是C ++?

    如果是C ++,创建一个包含bool(比如CMyBool)的新类,它会自动转换为bool。

    现在让LongFunction返回CMyBool(快速搜索和替换会将LongFuntion中的所有返回值更改为“返回CMyBool(x)”。

    现在在CMyBool的ctor中设置一个断点,调试器现在将在创建CMyBool时停止,这将在LongFunction中的正确返回语句上。

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

    这将使您了解最初的问题,但更大的问题是LongFunction需要重构。

    希望这可以帮助。

    如果你的问题只是普通的懒惰(没有错误),请确保LongFunction中的所有return语句都是

     return(value); 

    而不是

     return value; 

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

    然后,使用一个slighlty修改的预处理器宏比原始建议:

     #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中的步骤:

    我之所以说它取决于LongFunction的内容,是因为如果LongFunction从流中读取输入,或修改全局变量等,那么第二轮的行为可能会有所不同。 您应该将上述步骤视为代码如下:

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

    它是visual studio我会在断言上放置一个断点,然后使用堆栈跟踪窗口单击下一行,然后将进入该方法的退出点。

     #define return { TRACE(LINE); return; } 

    这解决了你的问题4。

    就其他问题而言,这就是编码的问题。 这就是为什么许多系统在出现问题时将更复杂的错误(例如来自COM对象的HRESULT)和/或垃圾邮件返回到调试流的原因。

    但是应该重新考虑1000行函数。 正如您所看到的那样,长期function难以维护。

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

     #define return TRACE(LINE), return 

    喝了几杯,所以可能没有。

    “我可能会逐步调试它,它可以工作,但很耗时,我们不会这样做。”

    你怎么调试?

    我曾经调试过:

    1)找到一组重现问题的参数。

    2)使用该组参数逐步执行代码。

    如果有1000行代码,那么如果不完全知道函数的function和应该做什么,你将如何“重构”。

    如果不单独执行该function,您将如何做到这一点。 我认为这是一个带有良好调试器的IDE。

    坦率地说,我发现这个问题几乎是一种非常悲伤的问题。

    1982年,我的任务是修复一个破碎的流程图程序。 该程序是用机器相关的Harris FORTRAN编写的(我现在不记得它是在FORTRAN IV还是FORTRAN 77中),由一个1100行的主程序,一个900行子程序和大约十几个子程序组成。长10到20行。

    哦,程序中几乎没有空格(空白行),评论根本没用。

    我花了160个小时 – 四个星期,全部时间,我的桌子上没有其他东西 – 弄清楚那些代码足以进行适当的修理。

    你处于类似的情况。 这将花费你真正的CPU时间投资,让你找到1000行的生物,足以解决所有可能出错的问题,以及如何解决它。

    找到回报很容易。 对于Microsoft AbysmalC ++:搜索“return”的每个实例并在其前面加上

    “printf(” n n — >>>在%d n n“,__LINE__行冲出);”

    (或您系统上的等效物)。 显然,你不能自动这样做; 你必须看看当地的包围。 然后运行测试,看看它告诉你的样子。

    事实是:在现实的计算世界里,几乎没有真正的例程,实际上需要1000行长。 在近40年的时间里,作为学生和专业人士,我只遇到了一个需要长于一个打印机页面(大约60行)的例行程序,而且这个例子非常特殊。 全部讲述了大约三页。

    另一方面,我已经看到很多运行模块,编写它的人太懒,或者太无能,无法正确地考虑因素,维护程序员太懒,太无能,或者太害怕他们的经理回去重构它。

    最后:考虑到这可能不是最后一次有人必须处理这个模块,而且可能不是你最后一次必须处理它。 这些东西往往是焦油宝宝:一旦你触摸它们,你永远不会脱离它们。 至少可能值得花时间进行重构,并且很可能从SCRATCH和第一原则重新设计/重写它。

      以上就是c/c++开发分享如何确定long函数返回的位置相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/545846.html

      (0)
      上一篇 2021年1月10日
      下一篇 2021年1月10日

      精彩推荐