4

我正在编写一个简单的宏来显示 TRACE 信息。

这就是我正在使用的,

#ifdef __DEBUG__
#define TRACE  { PrintErrorMsg("Trace exception at " __FILE__  "LineNo:"##(__LINE__) "Function: " __FUNCTION__ " " );}
#else 
#define TRACE 
#endif

这适用于FILE,但似乎不适用于LINE,知道我该如何处理。我也已经尝试过穿线运算符。如下所示。

#ifdef __DEBUG__
#define TRACE  { PrintErrorMsg("Trace exception at " __FILE__  "LineNo:"#(__LINE__) "Function: " __FUNCTION__ " " );}
#else 
#define TRACE 
#endif

并且没有 parms 和 double parms ,前 -__LINE__((__LINE__)) 任何想法我该如何处理这个问题?

我想出了这个,

#ifdef __DEBUG__
#define ERROR_MSG_BUF_SIZE 1024
#define TRACE  { char * error_msg_buffer = new char[ERROR_MSG_BUF_SIZE]; \
                 sprintf(error_msg_buffer,"Trace Exception at file: %s ,Line : %d , Function %s \n",__FILE__,__LINE__,__FUNCTION__);\
PrintErrorMsg(error_msg_buffer );\
delete[] error_msg_buffer;}
#else 
#define TRACE 

但我想在不使用 sprintf 的情况下做到这一点,只需通过字符串和令牌粘贴即可。任何的想法?

#endif

- 提前致谢 -

4

2 回答 2

16

当您尝试使用 对某些内容进行字符串化时#x,它x必须是一个宏参数:

#define FOO #__LINE__ /* this is not okay */
#define BAR(x) #x     /* this is okay */

但是你不能简单地说BAR(__LINE__),因为这会将标记传递给__LINE__BAR在那里它会立即变成一个没有扩展的字符串(这是设计使然),给出"__LINE__". 标记粘贴运算符也会发生同样的事情##:它们的操作数的扩展永远不会发生。

解决方案是添加间接性。你应该总是在你的代码库中的某个地方有这些:

#define STRINGIZE(x) STRINGIZE_SIMPLE(x)
#define STRINGIZE_SIMPLE(x) #x

#define CONCAT(first, second) CONCAT_SIMPLE(first, second)
#define CONCAT_SIMPLE(first, second) first ## second

现在STRINGIZE(__LINE__)转向STRINGIZE_SIMPLE(__LINE__)which 完全扩展为 (例如) #123,结果为“123”。呸!STRINGIZE_SIMPLE如果我想要原始行为,我会离开。所以你的代码会是这样的:

#include <iostream>

#define STRINGIZE(x) STRINGIZE_SIMPLE(x)
#define STRINGIZE_SIMPLE(x) #x

#define TRACE()                                                 \
        PrintErrorMsg("Trace exception in " __FILE__            \
                      " at line number " STRINGIZE(__LINE__)    \
                      " in function " __FUNCTION__ ".")

void PrintErrorMsg(const char* str)
{
    std::cout << str << std::endl;
}

int main()
{
    TRACE();
}
于 2012-11-09T03:19:14.857 回答
6

不幸的是,你需要这种愚蠢。

#include <stdio.h>

#define TRACE2(f,l) printf("I am at file: " f " and line: " #l "\n")
#define TRACE1(f,l) TRACE2(f,l)
#define TRACE() TRACE1(__FILE__, __LINE__)

int main(void)
{
    TRACE();
    TRACE();
}

我在文件:test.cpp 和行:9
我在文件:test.cpp 和行:10

于 2012-11-09T03:14:56.920 回答