【问题标题】:Error Logging C++ Preprocessor Macros __LINE__, __FUNCTION__错误记录 C++ 预处理器宏 __LINE__、__FUNCTION__
【发布时间】:2010-10-11 22:47:46
【问题描述】:

我试图将一个简单的错误日志记录合并到我现有的应用程序中,目前它只使用cout 报告错误,所以我希望使用<< 运算符保持类似的界面。但是我希望它记录发生错误的行和函数,但我不想每次需要记录时都输入__LINE__, __FUNCTION__。有谁知道我可以用来允许__LINE__ 宏在另一个函数中使用的技巧,而不是报告调用行?希望这是有道理的。

class myLogClass {
    uint8_t level;                  
public:                 
    bool operator<<( const char * input );          
};

bool myLogClass::operator<<( const char * input ) {
    logItInSQL( input );
    return true;
}

不是每次都这样

myLogClass << "Line No: " << __LINE__
    << " Function: " << __FUNCTION__
    << " Error: " << "This is my error to be logged";

我希望能够做到:

myLogClass << "This is my error to be logged";

bool myLogClass::operator<<( const char * input ) {
    logItInSQL( " Line No: __LINE__" );
    logItInSQL( " Function: __FUNCTION__" );
    logItInSQL( " Error: " + input );
    return true;
}

【问题讨论】:

    标签: c++ logging c-preprocessor


    【解决方案1】:
    myLogClass << "Line No: " << __LINE__ ...
    

    您的operator &lt;&lt; 链接将不起作用,因为它返回bool

    bool myLogClass::operator << (const char * input)
    

    习惯上这样定义流插入:

    std::ostream& myLogClass::operator << (std::ostream& o, const char * input) {
        // do something
        return o;
    }
    

    这样做:

    #define log(o, s) o << "Line No: " << __LINE__ << \
                       " Function: " << __FUNCTION__ << \
                       " Error: " << s // note I leave ; out
    

    此外,您可以将宏包装在 do-while 循环中:

    #define log(o, s) do { o << "Line No: " << __LINE__ << \
                       " Function: " << __FUNCTION__ << \
                       " Error: " << s; \ 
                      } while(0) // here, I leave ; out
    

    那你就可以愉快地写了:

     myLogClass myLogger; // do this
    
     // use it
    log(myLogger, "This is my error to be logged"); // note the ;
    

    【讨论】:

    • 好答案,只不过myLogClass是一个类,不是实例,所以他实际上需要实例化它并传递一个实例给log(instance,"message)
    • @thinkcube:谢谢!自我注意:永远不要从问题中复制粘贴。总是编译。
    【解决方案2】:

    在 ANSI C(我假设它也应该在 C++ 中工作)中,您可以使用可变参数函数和预处理器宏来做到这一点。请参见下面的示例:

    #include <stdio.h>
    #include <stdarg.h>
    
    #define MAXMSIZE 256
    #define MyDebug(...) MyInternalDebug(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)
    
    void MyInternalDebug( char *file, char *function, const int line, const char *format, ... )
    {
        char message[MAXMSIZE];
        // Variable argument list (VA)
        va_list ap;
        // Initialize VA
        // args : Name of the last named parameter in the function definition.
        // The arguments extracted by subsequent calls to va_arg are those after 'args'.
        va_start(ap, format);
    
        // Composes a string with the same text that would be printed if 'format' was used on printf,
        // but using the elements in the variable argument list identified by 'ap' instead of
        // additional function arguments and storing the resulting content as a C string in the buffer pointed by 'message'.
        // * The state of arg is likely to be altered by the call.
        vsprintf(message, format, ap);
        // Custom print function
        printf("%s\t%s\t%d\t%s\n",file, function, line, message);
    
        // Finzalize use of VA
        va_end(ap);
    }
    
    int main ()
    {  
        MyInternalDebug(__FILE__, __FUNCTION__, __LINE__, "An error occured with message = '%s'", "Stack Overflow");
        MyDebug("Another error occured with code = %d", 666);
    
        return 0;
    }
    

    【讨论】:

    • 可以,但通常我们避免使用 C++ 中的类 C 代码。
    【解决方案3】:

    不,这就是使用宏完成日志记录的原因。 __LINE__ 需要由相关行的预处理器扩展,而不是在常见的日志记录函数中。

    【讨论】:

      【解决方案4】:

      正如 Adam Mitz 所说,您需要在呼叫位置使用 __LINE__。
      我建议您添加一个额外的参数,例如“additionalInfo”,并创建一个宏,该宏将使用 __LINE__ 和 __FUNCTION__ 生成此“additionalInfo”。

      【讨论】:

        【解决方案5】:

        我无法获得第一个答案中的代码进行编译。我使用这个简单的宏很好地完成了任务:

        #define qlog(s) std::cerr &lt;&lt; __FUNCTION__ &lt;&lt; "::" &lt;&lt; __LINE__ &lt;&lt; "\t" &lt;&lt; s &lt;&lt; endl

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-04
          • 2020-02-09
          • 2011-01-26
          • 1970-01-01
          • 1970-01-01
          • 2010-12-18
          • 2014-04-17
          相关资源
          最近更新 更多