【问题标题】:Macro which prints an expression and evaluates it (with __STRING)打印表达式并对其进行评估的宏(使用 __STRING)
【发布时间】:2008-12-18 10:08:46
【问题描述】:

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

我当前的代码是:

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

然后:

PRINT(x & 0x01);

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

所以,我的问题:

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

【问题讨论】:

  • 我过去在搜索时遇到过类似的问题。 “.net”曾经是一个大的。
  • 您可以使用 google 搜索 StackOverflow,方法是使用 google 的站点:参数 :) 例如“__string site:stackoverflow.com”(没有返回任何内容)。

标签: c expression-evaluation


【解决方案1】:

类似

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

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

【讨论】:

    【解决方案2】:

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

    #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. Google 似乎工作正常。

    【讨论】:

    • 确实,在宏定义中使用#expr 就可以了。但是,那么您在很多地方(例如 assert() 源代码)发现的 __STRING 宏的意义何在?
    • __STRING 只是 # 的包装。它在 cdefs.h 中定义
    【解决方案3】:

    glibc 从(至少)1.04 版 (1992-09-03) 开始提供__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 两者都不提供。其他操作系统可能会有所不同。

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      • 2020-03-09
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多