令牌粘贴和__LINE__

时间:2012-11-09 02:49:37

标签: c++ file macros

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

这就是我正在使用的,

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

这适用于文件,但它似乎不适用于 LINE , 任何想法我怎么能处理这个。我已经尝试过使用字符串操作符。这就是 波纹管。

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

且没有参与和双重参与,前 - __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

- 提前致谢 -

2 个答案:

答案 0 :(得分:11)

当您尝试使用#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__),它完全展开到(例如)#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();
}

答案 1 :(得分:5)

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

#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