打印表达式并对其求值的宏(使用 __STRING)
为了学习和演示,我需要一个宏来打印其参数并对其进行评估。 我怀疑这是一个非常常见的案例,甚至可能是一个常见问题解答,但我找不到实际的参考资料。
我当前的代码是:
#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", __STRING(expr), (expr)))
然后:
PRINT(x & 0x01);
它工作正常,但我不确定 __STRING 宏的合法状态,特别是因为它位于私有 __ 命名空间中。
所以,我的问题是:
- 有没有更好的方法来编写这个宏?
- __STRING 是标准/伟大/邪恶吗?
- 如何利用现有的搜索工具来查找__STRING? SO 的搜索引擎只搜索包含字符串的任何内容:-(
For learning and demonstrating, I need a macro which prints its parameter and evaluates it. I suspect it is a very common case, may be even a FAQ but I cannot find actual references.
My current code is:
#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", __STRING(expr), (expr)))
and then:
PRINT(x & 0x01);
It works fine but I am not sure of the legal status of the __STRING macro, specially since it is in the private __ namespace.
So, my questions:
- Is there a better way to write this macro?
- Is __STRING standard/great/evil?
- How to use existing search tools to find about __STRING? SO's search engine just searches anything containing string :-(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
类似的东西
可能就是你想要的。 # 是字符串化运算符。
Something like
is probably what you want. # is the stringification operator.
您可以使用 # 预处理器标记,将其后面的参数转换为字符串文字:
这绝对不是标准的,这是我第一次遇到它; 这并不奇怪,因为乍一看,它似乎并没有比上面的 STR() 宏做更多的事情。
Google 似乎工作正常。
You can use the # preprocessor token which converts the parameter following it to a string literal:
It's definitely not standard, and this is the first time I've come across it; not surprising as it doesn't seem to do much more than the STR() macro above, at a first glance.
Google seems to work fine.
glibc 自(至少)版本 1.04 (1992-09-03) 甚至更早以来一直提供
__STRING
。/usr/include/sys/cdefs.h:
当时它们都在glibc中使用。 目前,
__STRING
未在 glibc 中使用,但保留在那里供应用程序使用。在 Linux 上,您可以依赖这些。 IIUC、
__STRING
和__CONCAT
在 NetBSD 1.3 中被采用; Solaris 两者都不提供。 其他操作系统可能有所不同。It is glibc who has been providing
__STRING
since (at least) version 1.04 (1992-09-03), maybe earlier./usr/include/sys/cdefs.h:
They were both used in glibc back then. Currently,
__STRING
is not used in glibc, but is kept there for app use.On Linux, you may rely upon these. IIUC,
__STRING
and__CONCAT
were adopted in NetBSD 1.3; Solaris provides neither. Other OSes may vary.对于产生可能未定义的值的宏,我能想到的最好的方法(可怕但有效):
然后你可以这样称呼它:
为要打印的每个宏复制这五行,并将 MACRO_NAME 替换为宏的名称。 在 PRINT_UNDEF 和 PRINT_INT 内部,您可以使用表达式而不仅仅是宏名称,但 #ifndef 必须仅包含宏名称。
The best I could come up with (horrible but working) for macros producing values that may be undefined:
And then you call it like
Copy these five lines for every macro that you want to print, and replace MACRO_NAME with the name of your macro. Inside the PRINT_UNDEF and PRINT_INT, you can use expressions instead of just macro names, but the #ifndef must contain just the macro name.