如何为多行宏调用获取宏名称 __LINE__?
Posted
技术标签:
【中文标题】如何为多行宏调用获取宏名称 __LINE__?【英文标题】:How to get macro name __LINE__ for a multi-line macro call? 【发布时间】:2012-11-09 18:25:57 【问题描述】:我创建了一个用于错误跟踪的宏。 这是一个简化的版本:
#include <stdio.h>
#define ERR(...) \
printf("error @ %d\n", __LINE__)
int main()
return ERR(1, /* line 7 */
2, /* line 8 */
3); /* line 10 */
执行时会打印:
error @ 10
但是,要将打印的行号与 grep
输出 (grep -n ERR test.c
) 匹配,我需要 ERR
字符串的行号 (line 7
)。
这样的事情可能吗?有什么想法吗?
补充说明:
宏应该看起来像一个函数调用(所以我可以做return ERR(...);
)。
编译器是 GCC 版本 4.4.5。可以使用 C99 + GNU 扩展。
【问题讨论】:
【参考方案1】:基于@cwyang 命题,在定义和逗号运算符中使用括号不匹配的宏。
#define ERR (LINEINFO, HANDLEARGS
#define HANDLEARGS(...) __LINE__)
#define LINEINFO printf("error @ %d: ", __LINE_)
return ERR(x,
y,
z);
将扩展到
return (printf("error @ %d: ", 5), 7);
使用 gcc。
【讨论】:
这似乎可以满足我的需求。谢谢! 哦,C 预处理器的乐趣。 哦,你好 5 年前的我。【参考方案2】:也许这是一个选项?
#define ERR(line,...) \
printf("error @ %d\n", line)
ERR(__LINE__
blah,
blah,
blah);
【讨论】:
(简单/理智的解决方案是根本不使用可变参数宏) 在非简化版本中,变量参数宏用于错误打印——它们无法避免。 不希望将__LINE__
s 写在所有地方(无论ERR
宏在哪里)。宏应尽可能少地使用参数。
@Lundin,我看不出这与变量参数宏有什么关系。
@AProgrammer 如果宏有一个参数或没有参数,那么不同的行格式设置是不可能的。【参考方案3】:
以下内容如何:
#define VOID_MACRO(...) (void) 0
#define ERR printf("err @ %d\n", __LINE__); VOID_MACRO
【讨论】:
它有一个问题:当ERR
用作return
值时,永远不会调用VOID_MACRO
(请参阅问题中的附加说明)。然而,它应该总是被调用——有一些使用可变参数的功能(在我的简化示例中没有显示)。
这部分解决了返回#define ARG_MACRO(...) returns1_and_processes_args(__VA_ARGS__) #define ERR printf("error @ %d: ", __LINE__) * ARG_MACRO
的问题。然而,这并不是一个完美的解决方案。以上是关于如何为多行宏调用获取宏名称 __LINE__?的主要内容,如果未能解决你的问题,请参考以下文章
Grafana - 如何为 Mysql 数据源创建 sql 查询部分变量/宏