- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个简单的宏来显示 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
没有参数和有双参数,例如 - __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
--提前致谢--
最佳答案
当您尝试使用 #x
将某些内容字符串化时,x
必须是一个宏参数:
#define FOO #__LINE__ /* this is not okay */
#define BAR(x) #x /* this is okay */
但是你不能简单地说 BAR(__LINE__)
,因为这会将 token __LINE__
传递给 BAR
,它会立即变成一个没有扩展的字符串(这是设计使然),给出 "__LINE__"
。 token 粘贴运算符 ##
也会发生同样的事情:它们的操作数的扩展永远不会发生。
解决方案是添加间接寻址。你应该总是在你的代码库中的某个地方有这些:
#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();
}
关于c++ - token 粘贴和 __LINE__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13301428/
我已经创建了一个用于错误跟踪的宏。这是一个简化版本: #include #define ERR(...) \ printf("
这个问题在这里已经有了答案: Creating C macro with ## and __LINE__ (token concatenation with positioning macro) (
我在头文件中有一个函数: template inline void log() {} 然后我尝试这个技巧来使它更容易使用: #define LOG_LINE log() 然后在 .cpp 文件中我这
我可以将 __LINE__ 用作方法参数就好了,但我想要一种在使用字符串的函数中使用它的简单方法。 例如说我有这个: 11 string myTest() 12 { 13 if(!
基本上,我的问题是 this除了 perl 而不是 PHP。 我知道warn() 管理它,但是warn() 是核心perl,所以我理解它是否通常不可能。 附录(以防链接最终失败) 有一个功能 sub
在 C/C++ 中,是否有一个宏会告诉我相对于找到该宏的函数开头的行号,而不是相对于文件开头的行号? 最佳答案 不,但是您可以通过创建行偏移来做一些等效的事情: int func(char *s) {
考虑一下我写的这个简短的程序: #include template constexpr int add(const int& a, const int& b) {
在另一篇文章 (Scala, Maven, and preprocessors) 中,我询问了有关使用 m4 等工具预处理 Java 和 Scala 的问题。我需要添加 __FILE__ 和 __LI
假设,我从下面的代码构建了一个独特的函数体: #define TOKENPASTE(x, y) x ## y #define TOKENPASTE2(x, y) TOKENPASTE(x, y) #d
所以,我感兴趣的是一个类似于 __LINE__ 的宏,但不是返回行号,而是返回给定行内的位置。 它可以是行中的列或字符位置。例如,在代码中: #define THISCHAR int main(voi
我阅读了有关使用 Cppreference 的宏的信息. __LINE__ : expands to the source file line number, an integer constant,
是否有可能通过LINE 宏获取在线报告的整个字符串。示例代码: #include #define LOG(lvl) pLog(lvl, __LINE__, __FILE__) pLog(const
在 C++ 中调试的一个有用的打印是 std::cout << __LINE__ << std::endl; 当然你可以简单地打印一个带有行号的字符串,例如: std::cout << "this i
我尝试使用以下方法打印当前代码的行号: #include void err (char *msg) { printf ("%s : %d" , msg , __LINE__); } int
我不明白以下程序的输出: #include #define FOO std::cout 2: 3: #define FOO std::cout #define __LINE__ 3 #defi
有没有什么方法可以在 Javascript 中获取源代码行号,比如 C 或 PHP 的 __LINE__? 最佳答案 有一种方法,虽然更昂贵:抛出异常,立即捕获它,并从其堆栈跟踪中挖掘出第一个条目。参
我想做一些异常处理。我计划使用 __LINE__ 和 __FILE__ 宏。 我有一些 header Vectors.hpp,我在其中为 vector 结构实现了一些类。在这个类中,我实现了 oper
我正在编写一些我想集成到库中的代码。我希望它没有外部依赖性并且符合标准。我想使用模板创建一个唯一的类型以允许编译时类型检查。 更新: 下面的代码来自msdn,这不是我尝试做的。我尝试做的是在用户每次使
我正在编写一个简单的宏来显示 TRACE 信息。 这是我用的, #ifdef __DEBUG__ #define TRACE { PrintErrorMsg("Trace exception at
为什么 __LINE__ 根据它是在类似函数的宏还是在常规函数中使用而进行不同的评估? 例如: #include #define A() printf("%d\n",__LINE__); int ma
我是一名优秀的程序员,十分优秀!