函数的隐式声明,无论头部是否包括ifndef

时间:2017-05-17 12:54:27

标签: c eclipse include-path implicit-declaration

我有众所周知的错误:

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'

阅读数十亿的帖子,询问如何在SO上解决这个问题,似乎有四个问题可能会导致这些错误:

  • 函数在main之后定义;
  • 包含使用函数所需的标题
  • #ifndef#define#endif未正确包装头文件

我找到了一个帖子,其中有人似乎有这个错误,并在修复它之后说Eclipse是问题所在。虽然无法找到主题,但他的解决方案并不适合我。这就像点击功能 source - &gt; 添加包含

的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.

一切似乎都很好,但编译器一直在大喊大叫。 如果需要,我会添加函数体,但我没有看到任何线索告诉函数体可能导致包含错误。我必须错过一些如此明显的东西,以至于我会在我看到它时没有人做过自我面孔。但我已经花了好几个小时,我希望这显然变得越来越薄了。

哦,昨天使用相同的包含路径和相同的目录构建它完全正常。我真的不知道自那以后发生了什么变化。

3 个答案:

答案 0 :(得分:3)

您没有证明您的<head> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <link href="https://fonts.googleapis.com/css?family=Noto+Sans|Ubuntu:700" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="styles.css"> </head> 文件有两个相当明显的

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

答案 1 :(得分:3)

正如您所呈现的那样,您的main.c包含对两个没有范围内声明的函数的调用:STLINKReadSytemCalls()printf()。这与编译器发出的警告(而不是错误)相关联,并且它是您提供的可以解释这些警告的唯一代码。

此时我强调

  1. 问题就在于我刚刚描述的内容:在调用这些函数时缺少范围内的函数声明。你的“可能导致这些错误的四个问题”(实际只有三个)描述了这些问题有时出现的各种具体途径;其中没有一个本身就是问题。

  2. 编译器发出警告,而不是错误。这意味着它接受了代码,但不能确定它是否正确使用它。特别是,它依赖于猜测参数列表的参数的数量和类型,并且它猜测函数返回int。这不安全,但如果你运气好,那么它可能会起作用,或者至少看起来如此。

  3. 鉴于问题是缺少函数声明,显然,解决方案是确保提供所有需要的声明,并且它们在引用这些函数的范围内。对于在同一C源中以外定义的函数,通常的解决方案是#include包含所需声明的头文件或文件。假设有问题的标题是正确编写的(标准库是,并且你提供的是内部标题库),那就是它的所有内容。

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

    来实现
    #include <stdio.h>
    #include "../header/fileProcessing.h"
    

    main.c的开头,正如@unwind已经建议的那样。这个改变足以满足我的编译器。

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

    顺便说一句,我补充一点,我发现fileProcessing.h #include标准stdio.hstdlib.h和{string.h #include有点奇怪(但并非错误) {1}}标题,即使它们对它们中的任何一个都没有依赖关系。作为样式规则,我强烈建议每个源文件(包括头文件)应fileProcessing.h直接使用的功能所需的所有标头,但不能使用其他标头。为了支持这一点,所有标题都应该具有适当的多包含保护,就像你提供的标题一样。

    因此,我会像这样重写#ifndef FILEPROCESSING_H_ #define FILEPROCESSING_H_ int STLINKReadSytemCalls(void); #endif /* FILEPROCESSING_H_ */

    #include

    ...并让其他文件根据需要处理^上述三个标准库标题中的任何一个或全部。

答案 2 :(得分:0)

可能重用了FILEPROCESSING_H_ symboh。 .h复制粘贴可能会发生