【问题标题】:Why does this C stringification macro corrupt whilst expanding?为什么这个 C 字符串化宏在扩展时会损坏?
【发布时间】:2012-02-08 21:11:40
【问题描述】:
#include <stdio.h>

#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
#define TEST one-of-a-linux

int main() {
  printf(EXPAND_AND_QUOTE(TEST)"\n");
}

我明白了:

1 中的一个

而不是

独一无二的linux

注意“linux”变成了“1”——即数字一

【问题讨论】:

  • 这意味着linux 是一个评估为1 的宏。
  • 如果你使用 gcc,你可能想尝试-std=c89-std=c99 来避免这个问题。
  • @CharlesBailey:第三方好奇,为什么会有帮助?
  • gcc 预定义了许多用户空间宏,例如 linuxunix,除非您将其置于更严格的标准兼容模式。
  • @CharlesBailey: -std=c99 正是我正在寻找的答案。谢谢。

标签: c macros stringify


【解决方案1】:

显然在某处有#define linux 1(或-Dlinux=1)。

【讨论】:

    【解决方案2】:
    #undef linux
    #define TEST one-of-a-linux
    

    【讨论】:

    • 在一般情况下可能不想这样做,以防之后包含任何其他系统标头(可能使用linux)。
    • undef linux 后面可以跟#define linux linux
    • @DanFego:如果它跟在给定示例中的 main 后面,则不会。一般来说,无论如何你都不会在标题中这样做......
    • @ugoren:可以。不要那样做。
    • @matt,我认为首先应该是#define linux linux。它可以让您询问#ifdef linux,但仅此而已。但是改变编译器定义的东西,即使你改进它,也确实不是你想做的事情。
    【解决方案3】:

    在我的 Linux 机器上:

    $ gcc -dM -E - < /dev/null | grep 'linux\|unix'
    #define __unix__ 1
    #define __linux 1
    #define __unix 1
    #define __linux__ 1
    #define __gnu_linux__ 1
    #define unix 1
    #define linux 1
    $
    

    注意unix 的值在 unix 平台上为 1 已用于 IOCCC 条目。 1987 年“Best One Liner”的获得者。

    http://www.ioccc.org/years.html#1987_korn

    代码是:

        main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
    

    【讨论】:

      【解决方案4】:

      您的代码中有一个#define 用于linux1。以下工作正常!

      #include <stdio.h>
      
      #undef linux
      
      #define QUOTE(str) #str
      #define EXPAND_AND_QUOTE(str) QUOTE(str)
      #define TEST one-of-a-linux
      
      int main(void) 
      {
          printf(EXPAND_AND_QUOTE(TEST)"\n");
          return 0;
      }
      

      输出:

      /*
      $ gcc mm.c 
      $ ./a.out 
      one-of-a-linux
      $ 
      */
      

      注意:

      #define TEST 1linux
      #define TEST linux1
      

      适当地打印预期的答案!

      【讨论】:

        猜你喜欢
        • 2021-12-28
        • 2022-07-06
        • 1970-01-01
        • 2015-07-22
        • 2011-03-01
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 2012-10-08
        相关资源
        最近更新 更多