错误记录 C++ 预处理器宏 __LINE__、__FUNCTION__

发布于 2024-07-15 02:59:05 字数 1011 浏览 4 评论 0原文

我试图将一个简单的错误日志合并到我现有的应用程序中,目前它仅使用 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;
}

I trying to incorporate a simple error logging into my existing app, at the moment it reports errors just using cout so I was hoping to keep a similar interface using the << operator. However I want it to log the line and function the error occurred, but I don't want to have to type __LINE__, __FUNCTION__ every time I need to log. Does anyone know a trick I can use to allow the __LINE__ macro to be used inside another function, reporting the calling line instead? Hope that makes sense.

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

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

Instead of this every time

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

I would like to just be able to do:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

南渊 2024-07-22 02:59:05
myLogClass << "Line No: " << __LINE__ ...

对于您的运算符<<,链接将不起作用,因为它返回一个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 << "Line No: " << __LINE__ ...

With your operator << chaining will not work since it returns a bool.

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

It is customary to define stream insertion as follows:

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

Do this:

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

Additionally, you can wrap the macro in a do-while loop:

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

Then you can happily write:

 myLogClass myLogger; // do this

 // use it
log(myLogger, "This is my error to be logged"); // note the ;
七颜 2024-07-22 02:59:05

在 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;
}

In ANSI C (which should also work in C++ I assume), you can do that using variadic functions and preprocessor macros. See example below:

#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;
}
对你的占有欲 2024-07-22 02:59:05

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

No, this is why logging is done with macros. __LINE__ needs to be expanded by the preprocessor on the line in question, not in a common logging function.

内心荒芜 2024-07-22 02:59:05

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

As Adam Mitz mentioned you need to use __LINE__ in the place of call.
I recommend to you to add an extra parameter like "additionalInfo" and create a macro that will generate this "additionalInfo" using __LINE__ and __FUNCTION__.

长梦不多时 2024-07-22 02:59:05

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

#define qlog(s) std::cerr << __函数__ << “::”<< __LINE__ << “\t”<< s << 结束

I could not get the code in the first answer to compile. I use this simple macro which accomplishes the task well:

#define qlog(s) std::cerr << __FUNCTION__ << "::" << __LINE__ << "\t" << s << endl

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文