【问题标题】:Why there is no semicolons after preprocessor directives?为什么预处理器指令后没有分号?
【发布时间】:2010-10-02 11:14:33
【问题描述】:

如果我写

#include <stdio.h>;

编译过程中没有错误但出现警告

pari.c:1:18:警告:#include 指令末尾的额外标记

是什么原因?

【问题讨论】:

  • 因为不需要
  • 在define后面加一个就明白了。

标签: c


【解决方案1】:

在编译期间,您的代码由两个独立的程序处理,即预处理器和编译器。预处理器首先运行。

您的代码实际上由两种语言组成,一种叠加在另一种之上。预处理器处理一种语言,即所有以“#”开头的指令(以及这些指令的含义)。它处理“#include”、“#define”和其他指令,并保持其余代码不变(好吧,除了预处理器指令的副作用,如宏替换等)。

然后编译器出现并处理预处理器生成的输出。它处理“C”语言,几乎忽略了预处理器指令。

您的问题的答案是“#include”是预处理器处理的语言的一部分,并且在这种语言中是“;”不是必需的,实际上是“额外的令牌”。

【讨论】:

    【解决方案2】:

    原因是预处理器指令不使用分号。这是因为他们使用换行符来分隔语句。这意味着每行不能有多个指令:

    #define ABC #define DEF // illegal
    

    但是你可以在每行(除了最后一行)用 \ (或者 /,我忘了)结束来在多行中使用一个。

    【讨论】:

      【解决方案3】:

      因为预处理器指令是包含在我们程序代码中的行,它们不是程序语句,而是预处理器的指令。

      这些预处理器指令仅在一行代码中扩展。一旦找到换行符,预处理器指令就被认为结束。这就是为什么在预处理器指令的末尾不需要分号 (;) 的原因。

      【讨论】:

        【解决方案4】:

        预处理器指令是与 C 不同的语言,并且具有更简单的语法,因为最初它们被“解析”,如果你可以调用它的话,在 C 编译器看到文件之前,由另一个名为 cpp 的程序。人们甚至可以使用它来预处理非 C 文件,以包含配置文件的条件部分等。

        有一个名为“unifdef”的 Linux 程序,如果您知道它们永远不会为真,您仍然可以使用它来删除程序的某些条件部分。例如,如果您有一些代码支持由#ifdef ANSI/#else/#end 或只是#ifndef ANSI/#end 包围的非ANSI 标准编译器,并且您知道您将不再需要支持非ANSI,您可以通过运行来消除死代码它通过unifdef -DANSI

        【讨论】:

          【解决方案5】:

          因为它们是不必要的。预处理器指令仅存在于一行,除非您明确使用行继续符(例如大宏)。

          【讨论】:

            【解决方案6】:

            如果您使用#define MACRO(para) fun(para);,则在其后面加上分号可能是错误的。

            if (cond) 
              MACRO (par1);
            else
              MACRO (par2);
            

            导致语法错误

            【讨论】:

              猜你喜欢
              • 2010-12-19
              • 2016-11-18
              • 2011-01-16
              • 2011-01-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多