【发布时间】:2010-10-02 11:14:33
【问题描述】:
如果我写
#include <stdio.h>;
编译过程中没有错误但出现警告
pari.c:1:18:警告:#include 指令末尾的额外标记
是什么原因?
【问题讨论】:
-
因为不需要
-
在define后面加一个就明白了。
标签: c
如果我写
#include <stdio.h>;
编译过程中没有错误但出现警告
pari.c:1:18:警告:#include 指令末尾的额外标记
是什么原因?
【问题讨论】:
标签: c
在编译期间,您的代码由两个独立的程序处理,即预处理器和编译器。预处理器首先运行。
您的代码实际上由两种语言组成,一种叠加在另一种之上。预处理器处理一种语言,即所有以“#”开头的指令(以及这些指令的含义)。它处理“#include”、“#define”和其他指令,并保持其余代码不变(好吧,除了预处理器指令的副作用,如宏替换等)。
然后编译器出现并处理预处理器生成的输出。它处理“C”语言,几乎忽略了预处理器指令。
您的问题的答案是“#include”是预处理器处理的语言的一部分,并且在这种语言中是“;”不是必需的,实际上是“额外的令牌”。
【讨论】:
原因是预处理器指令不使用分号。这是因为他们使用换行符来分隔语句。这意味着每行不能有多个指令:
#define ABC #define DEF // illegal
但是你可以在每行(除了最后一行)用 \ (或者 /,我忘了)结束来在多行中使用一个。
【讨论】:
因为预处理器指令是包含在我们程序代码中的行,它们不是程序语句,而是预处理器的指令。
这些预处理器指令仅在一行代码中扩展。一旦找到换行符,预处理器指令就被认为结束。这就是为什么在预处理器指令的末尾不需要分号 (;) 的原因。
【讨论】:
预处理器指令是与 C 不同的语言,并且具有更简单的语法,因为最初它们被“解析”,如果你可以调用它的话,在 C 编译器看到文件之前,由另一个名为 cpp 的程序。人们甚至可以使用它来预处理非 C 文件,以包含配置文件的条件部分等。
有一个名为“unifdef”的 Linux 程序,如果您知道它们永远不会为真,您仍然可以使用它来删除程序的某些条件部分。例如,如果您有一些代码支持由#ifdef ANSI/#else/#end 或只是#ifndef ANSI/#end 包围的非ANSI 标准编译器,并且您知道您将不再需要支持非ANSI,您可以通过运行来消除死代码它通过unifdef -DANSI。
【讨论】:
因为它们是不必要的。预处理器指令仅存在于一行,除非您明确使用行继续符(例如大宏)。
【讨论】:
如果您使用#define MACRO(para) fun(para);,则在其后面加上分号可能是错误的。
if (cond)
MACRO (par1);
else
MACRO (par2);
导致语法错误
【讨论】: