我在A
文件中定义了函数main.c
。我创建了三个使用函数A
而不导入任何内容的库。代码有效,但我只有一个警告:implicit declaration of function 'A' [-Wimplicit-function-declaration]
。
如果函数A
可以在单独的文件中定义的函数B
中工作而不导入它,怎么可能?
除了函数A
之外的其他函数调用函数B
时,我怎么可能只有一个警告?
答案 0 :(得分:5)
全局非静态符号(变量和函数)默认情况下具有外部linkage ,这意味着可以从其他translation units访问它们。< / p>
答案 1 :(得分:2)
在C
,我们没有&#34;导入&#34;功能。我们将单个翻译单元编译为目标文件,然后将它们链接在一起以形成二进制/可执行文件。
在链接阶段,链接器检查目标文件中是否有必需的符号和引用,并将它们链接在一起以生成单个可执行文件(从而在运行时调用函数)。
在您的情况下,编译器不会&#34;看到&#34;在调用时的函数声明(所以,它不知道函数签名,这可能是一个潜在的陷阱,这就是为什么你有&#34;警告&#34; ),但是在链接阶段,链接器能够找到对函数的引用(假设两个转换单元都链接在一起形成二进制文件)并创建二进制文件。
FWIW,根据最新的C标准,隐式函数声明是非标准的。在实际使用该函数之前,必须转发声明函数(提供原型)。引用C11
,前言,
第二版的主要变化包括:
[...]
- 删除隐式函数声明
答案 2 :(得分:1)
编译:
在编译期间,每个文件都是单独编译的,最后是.o 文件是从.c文件生成的。
对于文件编译器中调用的每个函数,期望函数定义或至少是函数的声明。
如果缺少定义或声明,您会收到编译器的警告,例如函数'A'的隐式声明 [-Wimplicit函数声明。
在您的情况下,由于函数定义在另一个文件中,您必须至少在包含文件中包含函数声明。
链接:
链接是指从中创建单个可执行文件
多个目标文件。在该步骤中,通常是链接器
会抱怨未定义的功能。
由于main.c中的函数A是全局定义的,因此库将使用它。