代码之家  ›  专栏  ›  技术社区  ›  abubacker

为什么预处理器给了一个空间?

  •  7
  • abubacker  · 技术社区  · 14 年前

    我想用预处理器注释一行:

    #define open /##*
    
    #define close */
    
    main()
    {
            open commented line close
    }
    

    当我这么做的时候 $gcc -E filename.c

    /* commented line */ 
    

    但我有

    / * commented line */ 
    

    所以编译器会显示一个错误

    为什么它会给一个不需要的空间?

    5 回复  |  直到 8 年前
        1
  •  3
  •   Greg Hewgill    14 年前

    能够 产生 /* #define ,编译器将看到 /* 并给出一个错误,因为它不是有效的C代码(它是预处理指令)。

    这似乎不是一件好事。

        2
  •  6
  •   Stephen C    14 年前

    来自GNU C预处理器文档:

    但是,不能将两个不在一起构成有效标记的标记粘贴在一起。例如,不能按任意顺序将x与+连接起来。如果您尝试,预处理器会发出警告并发出这两个标记。它是否在标记之间放置空格还没有定义。在复杂宏中,经常会发现不必要地使用“##”。如果收到此警告,很可能只需删除“##”。

    在这种情况下,'*’和'/'不会形成有效的C或C++令牌。所以它们之间有一个空间。

    (旁白:即使您设法将“注释”插入到C预处理器的输出中,也可能会出现C编译错误。这里不应该有任何评论。)

        3
  •  5
  •   kennytm    14 年前

    错误是因为 /* 不是有效的令牌。

    正如从 CPP doc

    x 具有 +

    你可以通过粘贴其他无意义的东西来得到错误。 /##+ +##-


    GCC source code :

        /* Avoid comment headers, since they are still processed in stage 3.
             It is simpler to insert a space here, rather than modifying the
             lexer to ignore comments in some circumstances.  Simply returning
             false doesn't work, since we want to clear the PASTE_LEFT flag.  */
          if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
            *end++ = ' ';
    
        4
  •  3
  •   Potatoswatter R. Martinho Fernandes    14 年前

    因为注释在预处理器运行之前(并且仅在运行之前)被替换为空格。如果你把这些字符粘在一起 / * 使用预处理器,你得到 /* 这只是几个运算符。 编辑: ## 技术上创造 作为单个标记,具有未定义的行为。你可以粘贴在一起 > ## > < %:%: : ,尽管你不应该。

    请参见C99的§6.4.6了解允许您构造的代币,以及6.10.3.3了解连锁过程。

        5
  •  0
  •   eyalm    14 年前

    如果要使用预处理器注释某些代码,请使用

    #if 0
    ...
    #endif