不管 header include 和 ifndef,函数的隐式声明

Implicit declaration of functions regardless of header include and ifndef

我有 well-known 个错误:

implicit declaration of function 'STLINKReadSytemCalls' [-Wimplicit-function-declaration]
implicit declaration of function 'printf' [-Wimplicit-function-declaration]
incompatible implicit declaration of built-in function 'printf'

Eclipse(更准确地说是 Atollic TrueStudio)请补充:

include '<stdio.h>' or provide a declaration of 'printf'

阅读数十亿 post 询问如何在 SO 上解决此问题,似乎三个问题可能导致这些错误:

我发现了一个 post,其中有人似乎有这个错误,并在修复它后说 Eclipse 是问题所在。虽然找不到主题,但他的解决方案对我不起作用。这有点像点击函数,source -> add includes.

main.c

int main(void) {

    if (STLINKReadSytemCalls() == 1)
        printf("Error in system calls.\n");
    return 0;
}

fileProcessing.c

#include "../header/fileProcessing.h"

int STLINKReadSytemCalls(void) {

    // mainly system calls
}

fileProcessing.h

#ifndef FILEPROCESSING_H_
#define FILEPROCESSING_H_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int STLINKReadSytemCalls(void);

#endif /* FILEPROCESSING_H_ */

最令人困惑的部分是代码确实有效。我有以下输出:

STM32 ST-LINK CLI v3.0.0.0
STM32 ST-LINK Command Line Interface

No ST-LINK detected
Unable to connect to ST-LINK!
Error in system calls.

一切似乎都很好,但编译器一直在大喊大叫。 如果需要,我将添加函数的 body,但我没有看到任何线索表明函数的 body 可能导致包含错误。我一定是遗漏了一些如此明显的东西,以至于当我看到它时,我会 self-facepalm 像从来没有人做过的那样;但我已经花了几个小时,我希望这很明显越来越薄。

哦,昨天使用相同的包含路径和相同的目录构建它工作得很好。我真的不知道从那以后发生了什么变化。

你没有表明你的 main.c 文件有两个相当明显的

#include <stdio.h>
#include "../header/fileProcessing.h"

行,是故意的吗?否则我认为这就是答案。

正如您介绍的那样,您的 main.c 包含对两个没有 in-scope 声明的函数的调用:STLINKReadSytemCalls()printf()。这与编译器发出的警告(不是错误)相关,并且这是您提供的代码中唯一可以解释这些警告的东西。

这里我强调一下

  1. 问题就是我刚才描述的:在调用这些函数的地方缺少in-scope函数声明。您的"four problems [that] might cause these errors"(实际只提供了三个)描述了有时会出现此类问题的各种具体途径; none 本身就是问题所在。

  2. 编译器发出警告,而不是错误。这意味着它接受了代码,但不能确定它对它做了正确的事情。特别地,它依赖于参数的数量和类型来猜测参数列表,并且它猜测函数 return int。这并不安全,但如果你幸运的话,它可能会奏效,或者至少看起来会奏效。

鉴于问题是缺少函数声明,解决方案显然是确保提供所有需要的声明,并且它们在引用这些函数的范围内。对于在同一 C 源代码之外的其他地方定义的函数,通常的解决方案是 #include 一个 header 文件或包含所需声明的文件。假设所讨论的 header 编写得当(标准库是,而您提供的内部库是),仅此而已。

您的项目布局并不完全清楚,但看起来您可以通过将

#include <stdio.h>
#include "../header/fileProcessing.h"

main.c 的开头,正如@unwind 已经建议的那样。该更改足以满足 my 编译器的要求。

您建议这样做会导致您的原始代码出现其他类型的问题。如果那是真的,那么这将构成一个完全不同的问题,如果您无法弄清楚,那么您可以考虑在这里提出。在提出的 this 问题中没有暗示这样的问题,作为一个完全独立的问题,在这里提出这个问题是不合适的。


顺便说一句,我发现您的 fileProcessing.h #include 是标准的 stdio.hstdlib.h 有点奇怪(但没有错)和 string.h headers 即使它不依赖于它们中的任何一个。作为风格规则,我强烈建议每个源文件,包括 header 文件,应该 #include 它们直接使用的功能所需的所有 header,但没有其他。为了支持这一点,所有 header 还应该有适当的 multiple-inclusion 守卫,正如你所提供的 header 实际上那样。

因此,我会这样重写 fileProcessing.h

#ifndef FILEPROCESSING_H_
#define FILEPROCESSING_H_

int STLINKReadSytemCalls(void);

#endif /* FILEPROCESSING_H_ */

... 并让其他文件根据需要处理 #includeing 上述三个标准库中的任何一个或所有 header。

可能是 FILEPROCESSING_H_ 符号的重用。 .h 复制粘贴可能会发生