令牌粘贴和__LINE__

san*_*ika 3 c++ macros file

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

这就是我正在使用的,

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

这与FILE一起使用,但它似乎不适用于LINE,任何想法我怎么能处理这个.我已经尝试过使用字符串操作符.这是如下所示.

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

没有parms和双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 
Run Code Online (Sandbox Code Playgroud)

但是我想在不使用sprintf的情况下完成它,只需要通过穿线和标记粘贴.任何的想法?

#endif
Run Code Online (Sandbox Code Playgroud)

- 提前致谢 -

GMa*_*ckG 11

当您尝试使用字符串化时#x,x必须是宏参数:

#define FOO #__LINE__ /* this is not okay */
#define BAR(x) #x     /* this is okay */
Run Code Online (Sandbox Code Playgroud)

但是你不能简单地说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
Run Code Online (Sandbox Code Playgroud)

现在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();
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*rtz 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();
}
Run Code Online (Sandbox Code Playgroud)

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