Kak*_*aka 0 c compiler-construction linker loops
我想知道包含文件的无限循环是否会导致编译器问题或链接器问题.我试过这个:
/* file : try.c */
#include "try1.c"
int main(void) {}
/* file : try1.c */
#include "try.c"
int a(void) { return 0; }
Run Code Online (Sandbox Code Playgroud)
编译命令是:
gcc -Wall try.c -o try
Run Code Online (Sandbox Code Playgroud)
这显然会导致很长的输出(像这样开始):
try.c:5:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
In file included from try.c:1:0,
from try1.c:1,
from try.c:1:
try1.c:4:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
In file included from try1.c:1:0,
from try.c:1:
try.c:5:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
In file included from try.c:1:0:
try1.c:4:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
try.c:5:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
In file included from try.c:2:0,
from try1.c:1,
from try.c:1,
from try1.c:1,
from try.c:1,
from try1.c:1,
from try.c:1,
from try1.c:1,
from try.c:1,
from try1.c:1,
.
.
etc...
Run Code Online (Sandbox Code Playgroud)
嗯,显然这里有一个无限循环.但什么时候发生?在编译过程中还是链接器?我想你将在编译过程中告诉我,因为它将在这里定义多个具有相同名称的函数(因为循环),但不是unite文件在链接器进程中出现的部分(然后在那里只有一个文件没有编译问题)?
谢谢 !
实际上,#include- 类型语句的扩展称为"预处理"步骤.我曾经认为这些步骤都是在任何"编译"发生之前作为一个单独的步骤处理的,但@EricPostpischil在评论中指出(并举例说明它)这两件事 - 预处理和编译 - 似乎发生了并发(如源文件中的行顺序所指示的).换句话说,#命令的扩展("预处理器指令")是"在编译发生时"完成的.从这个意义上说,错误是一个"编译"错误; 但在我看来,说" #include预处理器处理的内容" 是有效的.当编译器处理"预处理器步骤"时,该行模糊.绝对不是引起问题的链接器 - 编译器在你进入该步骤之前就已经放弃了.
作为一般性评论,将#include一个.c文件放在另一个文件中并不是一个好习惯- 这就是链接器应该用于的内容.并且为了防止"递归包含",您经常.h会在编译器附带的文件中看到这样的结构:
#ifndef __MYINCLUDEFILE
#define __MYINCLUDEFILE
... put the body of the include file here
#endif
Run Code Online (Sandbox Code Playgroud)
这确保了包含文件只包含一次,即使它是从多个地方调用的(第一次包含它,__MYINCLUDEFILE变量将被定义;下次包含它时,将跳过整个函数体).一旦你对每个包含文件执行此操作,您所遇到的那种"递归陷阱"就不再发生了.
正如@wildplasser所指出的那样,语言和实现的使用_NAME和__NAME保留 - 我使用它作为一个例子,因为你会在编译器附带的头文件中看到这样的结构.当您创建自己的.h文件时,您必须考虑另一个创建唯一标识符的约定.
| 归档时间: |
|
| 查看次数: |
373 次 |
| 最近记录: |