C++ 如何确定长函数返回的位置
假设有一个名为LongFunction的1000行代码的函数,我们使用它:C++ 如何确定长函数返回的位置,c++,c,return,C++,C,Return,假设有一个名为LongFunction的1000行代码的函数,我们使用它: bool bSuccess = LongFunction(); assert(bSuccess); 这里我在调试时得到了一个断言,我知道LongFunction有问题,所以我需要找到函数在哪里遇到问题并返回: 我可能可以一步一步地调试它,它可以工作,但很耗时,我们不知道如何用这种方式进行调试 我可以搜索关键字“return”(或者更精细的搜索使用RegExp),并在这些返回处设置断点,应该会更快,但这仍然是繁琐的手工工
bool bSuccess = LongFunction();
assert(bSuccess);
这里我在调试时得到了一个断言,我知道LongFunction有问题,所以我需要找到函数在哪里遇到问题并返回:
- 由于经常使用return,它将打印太多的冗余信息。(或者我们可以使用一些EnvVar来打开或关闭它)
- 不适用于以下情况:if(bOK)返回true李>
我们有一些争议:
是的,每个人都知道我们应该这样做,但这不是重点。如果我打电话重构函数,我不会在这里问这个问题
我要做的第一件事就是找到错误发生的地方,然后知道发生了什么,我很好奇为什么这样做没有帮助,在这种情况下你做了什么?(假设我已经熟悉该函数的工作原理)
听起来是时候重构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
条件1(bSuccess==0)
break f.cc:4
Jump f.cc:4
我之所以说这取决于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;
// ...
}