【问题标题】:Is it possible to print a preprocessor variable in C?是否可以在 C 中打印预处理器变量?
【发布时间】:2010-11-15 07:23:58
【问题描述】:

是否可以将 C 中预处理器变量的值打印到 stderr?例如,我现在拥有的是:

#define PP_VAR (10)
#if (PP_VAR > 10)
    #warning PP_VAR is greater than 10
#endif

但我想做的是:

#define PP_VAR (10)
#if (PP_VAR > 10)
    #warning PP_VAR=%PP_VAR%
#endif

C 中可以实现这样的事情吗?

【问题讨论】:

    标签: c variables c-preprocessor


    【解决方案1】:

    您可以在 Visual Studio 下打印出预处理器变量的值。下面打印出 _MSC_VER 的值:

    #define STRING2(x) #x
    #define STRING(x) STRING2(x)
    
    #pragma message(STRING(_MSC_VER))
    

    但不确定这有多标准。

    【讨论】:

    • 它不是标准的,但是 GCC、MSVC、CLANG...(可能其他人也支持它)
    • VisualStudio 显然不是
    • @derHugo:抱歉,我刚刚使用 Visual Studio 2017 和 C++17 进行了测试,而且这项工作没有问题。我使用自定义预处理器变量进行了测试,而不是 _MSC_VER !
    【解决方案2】:

    这适用于 GCC 4.4.3:

    #define STRING2(x) #x
    #define STRING(x) STRING2(x)
    #pragma message "LIBMEMCACHED_VERSION_HEX = " STRING(LIBMEMCACHED_VERSION_HEX)
    

    产量:

    src/_pylibmcmodule.c:1843: note: #pragma message: LIBMEMCACHED_VERSION_HEX = 0x01000017
    

    【讨论】:

      【解决方案3】:

      许多 C 编译器都支持#warning(但它不是由 C 标准定义的)。

      但是,GCC 至少不会对后面的数据做预处理,这意味着很难看到变量的值。

      #define PP_VAR 123
      #warning "Value of PP_VAR = " PP_VAR
      #warning "Value of PP_VAR = " #PP_VAR
      #warning "Value of PP_VAR = " ##PP_VAR
      

      GCC 产生:

      x.c:2:2: warning: #warning "Value of PP_VAR = " PP_VAR
      x.c:3:2: warning: #warning "Value of PP_VAR = " #PP_VAR
      x.c:4:2: warning: #warning "Value of PP_VAR = " ##PP_VAR
      

      【讨论】:

      • 所以当你说“很难看到变量的值”时,你真正的意思是你看不到它。
      • 大致 - 是的;我还没想出办法去看,和“没办法看到”不一样。
      • 认为这就是我想要做的......我想知道运行时库将SSIZE_MAX定义为什么作为字符串(如0INT_MAXLONG_MAX),但字符串仅返回SSIZE_MAX(定义的左侧)。
      【解决方案4】:

      使用预处理器标记粘贴运算符:##TOKEN_NAME

      如前所述,您使用的预处理器指令是非标准的,因此是 YMMV。

      【讨论】:

        【解决方案5】:

        嗯,你所做的实际上是非标准的。首先,“#warning”或“#warn”指令不是标准的。其次,使用预处理器时,行必须以井号开头,不能有空格:

        #ifdef BLAH1 #define BLAH2 // 好的,因为磅在最左边。 #万一 #ifdef BLAH3 #define BLAH4 // 适用于许多编译器,但不是标准的。 #万一

        由于您已经在使用非标准扩展,因此您需要查看您正在使用的特定预处理器/编译器的文档,以了解其中关于“#warning”的内容。

        【讨论】:

        • 您的第二点不正确 - C89 取消了该限制。 # 必须是该行的第一个符号,但它前面可以有空格(但不能是 cmets)。
        • 谢谢。我不敢相信我还生活在黑暗时代。你能指出我的相关文件吗?
        • 哇。我参加比赛的时间比我想象的要晚——我根本不知道这个限制。
        • @Jonathan:在任何带有注释的预处理指令之前(至少 c 注释 /*..*/)完全没有问题,它将在翻译阶段 #3 中替换为单个空格。预处理指令在第 4 阶段处理,因此不受前面 c 注释的影响。
        • @Artur:你是对的——但在过去糟糕的日子里(真的是过去的日子,C89 之前的标准日子),不允许使用 cmets。我的混音。 (请注意,必须有一个非常非常好的理由在预处理器指令之前包含注释,我想不出任何理由。)
        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2011-04-19
        • 1970-01-01
        • 2013-04-19
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多