在使用了几年又大又丑的MFC ASSERT宏之后,我终于决定放弃它,创建一个终极的ASSERT宏。
我可以很好地获得文件和行号,甚至失败的表达式。我可以显示一个消息框,其中包含这些,以及中止/重试/取消按钮。
当我按下Retry时,VS调试器会跳转到包含ASSERT调用的行(而不是像其他ASSERT函数那样进行反汇编)。
但真正酷的是 * 显示失败的函数的名称 *。
然后我就可以决定是否调试它,而不必试图从文件名猜测它在哪个函数中。
例如,如果我有以下函数:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ASSERT(lpCreateStruct->cx > 0);
...
}
然后,当ASSERT触发时,消息框将显示如下内容:
Function = CMainFrame::OnCreate
那么,在运行时找到当前函数名的最简单方法是什么?
- 它不应该使用MFC或.NET框架,即使我使用这两个。
它应该尽可能地便携。*
8条答案
按热度按时间pzfprimi1#
您的宏可以包含
__FUNCTION__
宏。请不要搞错,函数名将在编译时**插入到扩展代码中,但它将是每次调用您的宏的正确函数名。因此,它“看起来”是在运行时发生的;)例如
djmepvbi2#
C++预处理器宏
__FUNCTION__
给出了函数的名称。注意,如果你使用这个,它并不是在运行时获取文件名、行号或函数名。宏是由预处理器展开并编译的。
示例程序:
输出:
92vpleto3#
没有标准的解决方案。但是,
BOOST_CURRENT_FUNCTION
对于所有实用目的都是可移植的。头部不依赖于任何其他Boost头部,因此如果整个库的开销不可接受,可以单独使用。pdkcd3nj4#
__FUNCTION__
或__FUNC__
或__PRETTY_FUNCTION__
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspxhttp://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
iqjalb3h5#
在GCC中,你可以使用
__PRETTY_FUNCTION__
宏。微软也有一个等效的
__func__
宏,虽然我没有可用的尝试。例如,使用
__PRETTY_FUNCTION__
,在函数的开头放置这样的内容,您将获得完整的跟踪它将输出
如果你想输出更多的信息,你还可以在所有标准的c/c++编译器下使用
__FILE__
和__LINE__
宏。在实践中,我有一个特殊的调试类,我用它来代替cout。通过定义适当的环境变量,我可以得到完整的程序跟踪。你可以做类似的事情。这些宏非常方便,能够在现场打开这样的选择性调试真是太棒了。
编辑:显然
__func__
是标准的一部分?我不知道。不幸的是,它只给出了函数名,而不是参数。我确实喜欢gcc的__PRETTY_FUNC__
,但它不能移植到其他编译器。GCC还支持
__FUNCTION__
。vqlkdk9b6#
您可以使用
__FUNCTION__
macro,它在编译时将扩展为函数的名称。下面是一个如何在Assert宏中使用它的例子。
8oomwypt7#
C++20
std::source_location::function_name
现在不需要宏了,因为我们已经有了适当的标准化:
main.cpp
编译并运行:
输出:
因此,请注意呼叫如何保留呼叫者信息,因此我们看到的是所需的
main
呼叫位置,而不是log
。我在以下网站更详细地介绍了相关标准:PRETTY_FUNCTION、FUNCTION、__func__之间有什么区别?
在Ubuntu 22.04,GCC 11.3上测试。
acruukt98#
你可以很容易地使用func.它会在运行时取回你当前的函数名,这引发了异常.
使用方法: