8

为了学习和演示,我需要一个宏来打印其参数对其进行评估。我怀疑这是一个非常常见的案例,甚至可能是一个常见问题解答,但我找不到实际的参考资料。

我目前的代码是:

#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", __STRING(expr), (expr)))

进而:

PRINT(x & 0x01);

它工作正常,但我不确定 __STRING 宏的法律地位,特别是因为它位于私有 __ 命名空间中。

所以,我的问题:

  1. 有没有更好的方法来编写这个宏?
  2. __STRING 是标准的/伟大的/邪恶的吗?
  3. 如何使用现有的搜索工具查找有关 __STRING 的信息?SO的搜索引擎只搜索包含字符串的任何内容:-(
4

3 回答 3

13

就像是

#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", #expr, (expr)))

可能是你想要的。# 是字符串化操作符。

于 2008-12-18T10:20:16.457 回答
11

您可以使用 # 预处理器标记,它将后面的参数转换为字符串文字:

#include <stdlib.h>
#include <stdio.h>

#define STR(x) #x
#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", STR(expr), (expr)))

int main(void)
{
    int x = 7;

    PRINT(x & 0x01);

    return EXIT_SUCCESS;
}
  1. 这绝对不是标准的,这是我第一次遇到它;乍一看,它似乎并没有比上面的 STR() 宏做更多的事情。

  2. 谷歌似乎工作正常。

于 2008-12-18T10:15:54.827 回答
0

从(至少)版本 1.04 (1992-09-03)开始提供的是glibc ,可能更早。__STRING

/usr/include/sys/cdefs.h:

#define __CONCAT(x,y)   x ## y
#define __STRING(x) #x

当时它们都在 glibc 中使用。目前,__STRING没有在 glibc 中使用,但保留在那里供应用程序使用。

在 Linux 上,您可以依赖这些。IIUC,__STRING__CONCAT在 NetBSD 1.3 中被采用;Solaris 两者都不提供。其他操作系统可能会有所不同。

于 2021-09-08T12:39:21.243 回答