相关疑难解决方法(0)

在C++中__FILE __,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

假设您的C++编译器支持它们,是否有任何特殊原因使用__FILE__,__LINE__以及__FUNCTION__用于记录和调试目的?

我主要关注的是为用户提供误导性数据 - 例如,由于优化而报告错误的行号或功能,或者因此导致性能下降.

基本上,我可以信任__FILE__,__LINE____FUNCTION__永远做正确的事?

c++ debugging logging c-preprocessor

149
推荐指数
6
解决办法
23万
查看次数

用C或C++打印调用堆栈

有没有办法在每次调用某个函数时在C或C++中正在运行的进程中转储调用堆栈?我的想法是这样的:

void foo()
{
   print_stack_trace();

   // foo's body

   return
}
Run Code Online (Sandbox Code Playgroud)

其中的print_stack_trace工作方式类似于callerPerl.

或类似的东西:

int main (void)
{
    // will print out debug info every time foo() is called
    register_stack_trace_function(foo); 

    // etc...
}
Run Code Online (Sandbox Code Playgroud)

在哪里register_stack_trace_function放置某种内部断点,这将导致在调用时打印堆栈跟踪foo.

在某些标准C库中是否存在这样的事情?

我正在使用GCC在Linux上工作.


背景

我有一个测试运行,基于一些不应该影响此行为的命令行开关,行为不同.我的代码有一个伪随机数生成器,我假设它是基于这些开关被不同地调用的.我希望能够使用每组开关运行测试,并查看随机数生成器是否针对每个开关进行不同的调用.

c c++ linux callstack

98
推荐指数
8
解决办法
15万
查看次数

可用于打印方法名称的宏/关键字?

__FILE__并且__LINE__众所周知.__func__自C99以来有一个.

#include <iostream>
struct Foo {
        void Do(){ std::cout << __func__ << std::endl; }
};

int main()
{
        std::cout << __func__ << std::endl;
        Foo foo; foo.Do();
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

将输出

main
Do
Run Code Online (Sandbox Code Playgroud)

是否有任何输出方法名称的宏/关键字Foo::Do

c c++

43
推荐指数
2
解决办法
2万
查看次数

如何在运行时找到当前函数的名称?

经过多年使用丑陋的MFC ASSERT宏,我终于决定抛弃它并创建最终的ASSERT宏.

我很好地获取文件和行号,甚至是失败的表达式.我可以显示带有这些的消息框,以及中止/重试/取消按钮.

当我按下Retry时,VS调试器会跳转到包含ASSERT调用的行(而不像某些其他ASSERT函数那样反汇编).所以这一切都非常有效.

但真正酷的是显示失败的函数的名称.

然后我可以决定是否调试它而不试图从文件名中猜出它的功能.

例如,如果我有以下功能:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   ASSERT(lpCreateStruct->cx > 0);
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后当ASSERT触发时,消息框将显示如下内容:

Function = CMainFrame::OnCreate
Run Code Online (Sandbox Code Playgroud)

那么,在运行时找到当前函数名的最简单方法是什么?

它不应该使用MFC或.NET框架,即使我确实使用这两者.
它应该尽可能便携.

c++ assert function

36
推荐指数
6
解决办法
5万
查看次数

在编译时打印模板typename

在C++中创建模板函数时,有一种简单的方法可以将模板的类型名称表示为字符串吗?我有一个简单的测试用例来展示我正在尝试做的事情(注意显示的代码不能编译):

#include <stdio.h>
template <typename type>
type print(type *addr) 
{
  printf("type is: %s",type);
}

int main()
{
  int a;
  print(&a);
}

// Would like to print something like:
// type is: int
Run Code Online (Sandbox Code Playgroud)

我认为在实例化函数时,typename应该在编译时可用,但我不熟悉模板,我还没有看到将typename作为字符串的方法.

我想这样做的原因是一些printf类型的调试.我有多个线程正在运行,并通过gdb逐步更改程序行为.所以对于某些事情,我想转储有关正在执行哪些函数的信息.这不是太重要,所以如果解决方案过于复杂,我会跳过将此信息添加到我的日志记录功能中.但如果有一种简单的方法可以做到这一点,那将是有用的信息.

c++ g++

34
推荐指数
5
解决办法
2万
查看次数

有没有办法在C++函数中获取函数名?

我想实现一个函数跟踪器,它将跟踪一个函数执行的时间.我有以下课程: -

class FuncTracer
{
    public:
        FuncTracer(LPCTSTR strFuncName_in)
        {
            m_strFuncName[0] = _T('\0');
            if( strFuncName_in ||
                _T('\0') != strFuncName_in[0])
            {   
                _tcscpy(m_strFuncName,strFuncName_in);

                TCHAR strLog[MAX_PATH];
                _stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
                LOG(strLog)

                m_dwEnterTime = GetTickCount();
            }
        }

        ~FuncTracer()
        {
            TCHAR strLog[MAX_PATH];
            _stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
            LOG(strLog)
        }

    private:
        TCHAR m_strFuncName[MAX_PATH];
        DWORD m_dwEnterTime;
};

void TestClass::TestFunction()
{
    // I want to avoid writing the function name maually..
    // Is there any macro (__LINE__)or some other way to 
    // get the function …
Run Code Online (Sandbox Code Playgroud)

c++ macros profiling

26
推荐指数
3
解决办法
4万
查看次数

函数名__func__的预定义宏

我正在尝试构建一个调试日志消息函数,该函数记录调用日志消息的位置的文件,行和函数.

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __func__ , __FILE__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于某些编译器,但不是全部.我的代码需要与GCC以及Microsoft Visual工作室交叉兼容.我已添加以下定义以帮助兼容性.

#ifndef __FUNCTION_NAME__
    #if defined __func__ 
        // Undeclared 
        #define __FUNCTION_NAME__   __func__ 
    #elif defined __FUNCTION__ 
        // Undeclared
        #define __FUNCTION_NAME__   __FUNCTION__  
    #elif defined __PRETTY_FUNCTION__
        // Undeclared
        #define __FUNCTION_NAME__   __PRETTY_FUNCTION__
    #else
        // Declared
        #define __FUNCTION_NAME__   "N/A"   
    #endif // __func__ 

#endif // __FUNCTION_NAME__

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __FUNCTION_NAME__, __FILE__, __LINE__ );
Run Code Online (Sandbox Code Playgroud)

上面代码片段的问题在于#else宏在所有编译器上都处于活动状态,而其他宏则没有.换句话说#if defined __func__,在编译器上是假的,其中__func__ …

c++ gcc visual-studio c-preprocessor

20
推荐指数
4
解决办法
4万
查看次数

Visual C++相当于__FILE __,_ _ _ ____和__PRETTY_FUNCTION__

GCC编译器给我以下宏:

  • __FILE__ 这样我就可以打印出文件名+目录了.
  • __LINE__ 这样我就可以打印出我要打印的行号.
  • __PRETTY_FUNCTION__ 这样我就可以打印出漂亮的功能名称了

Visual C++是否具有这些宏的等价物?一个侧面问题是,这些是C++编译器的标准吗?

c++ compiler-construction gcc visual-c++

19
推荐指数
4
解决办法
2万
查看次数

将__func__视为字符串文字而不是预定义的标识符

我正在使用gcc编译C99代码.我想写一个宏,它将返回一个包含函数名和行号的字符串.

这就是我所拥有的:

#define INFO_MSG  __FILE__ ":"__func__"()"
Run Code Online (Sandbox Code Playgroud)

但是,当我编译试图使用此字符串的代码时,例如:

char buff[256] = {'\0'}
sprintf(buff, "Something bad happened here: %s, at line: %d", INFO_MSG, __LINE__);
printf("INFO: %s\n", buff);
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

error: expected ‘)’ before ‘__func__’
Run Code Online (Sandbox Code Playgroud)

我已将问题跟踪到宏.当我__func__从宏中删除时,代码正确编译.

如何修复宏,以便我可以__func__在我的字符串中包含预定义的宏?

c macros

15
推荐指数
1
解决办法
9106
查看次数

如何使用gcc模仿Microsoft版本的__FUNCTION__?

当我使用__FUNCTION__宏/变量打印出调试信息时,使用Microsoft C++编译器和gcc时输出的内容似乎有所不同.例如,使用以下简单代码:

class Foo 
{
    public:
       void Bar(int a, int b, int c)
       {
           printf ("__FUNCTION__ = %s\n", __FUNCTION__);
       }
};

int main (void)
{
    Foo MyFoo;

    MyFoo.Bar();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了使用Microsoft Visual C++编译器

__FUNCTION__ = Foo::Bar
Run Code Online (Sandbox Code Playgroud)

而在使用gcc编译时(在本例中是在Mac上),我得到了

__FUNCTION__ = Bar
Run Code Online (Sandbox Code Playgroud)

第二个例子并不理想,因为我经常有几个类,比方说Init()Uninit()方法,并且在调试输出跟踪中,几乎不可能知道哪个类被调用,因为类名将丢失.现在,我知道你可以使用__PRETTY_FUNCTION__代替它__FUNCTION__来获得类似的东西

__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int)
Run Code Online (Sandbox Code Playgroud)

这很好,但它对于我需要的东西有点过于冗长,并且对于具有大量参数的函数来说有点长.

所以我的问题是(最后),有没有办法让输出看起来像简单地Foo::Bar使用gcc,如上例所示?

c++ windows compiler-construction macos gcc

8
推荐指数
1
解决办法
2639
查看次数