我正在编写一个简单的宏来显示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
- 提前致谢 -
答案 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