3

I have the well-known errors :

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

And Eclipse (Atollic TrueStudio more precisely) kindly added :

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

Reading the billions of post asking how to solve this problem on SO, it seems that three problems might cause these errors :

  • Functions are defined after main;
  • Required headers to use a function are included
  • #ifndef, #define and #endifdo not correctly wrap the header files

I have found a post in which someone seemed to have this error and said after fixing it that Eclipse was the problem. Can't find the topic though, but his solution didn't work for me. It was something like clicking on the function, 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_ */

The most confusing part is that the code actually works. I have the following output :

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.

Everything seems to be fine, but compiler keeps yelling. I'll add the function's body if needed, but I have seen nowhere any clue telling that a function's body could cause an include error. I must be missing something so obvious that I'll self-facepalm like no one ever did when I'll see it; but I have already spent hours and my hope that this is obvious is getting thinner.

Oh, and yesterday with the same include path and same directory build it worked perfectly fine. I really don't know what changed since.

Badda
  • 1,329
  • 2
  • 15
  • 40
  • 4
    When working with Eclipse, it is perfectly normal to spend a a week or so per project chasing down all mysterious path and include errors. – Lundin May 17 '17 at 14:25
  • @Lundin Honestly this is so mysterious I think Eclipse does cause my problems. Is there any logical and reproductible way to fix those errors generally ? – Badda May 17 '17 at 14:29
  • Note [What are the benefits of a relative path such as "../include/header.h" for a header?](http://stackoverflow.com/questions/597318) Generally, you're best off avoiding the `..` notation in the source files including a header. – Jonathan Leffler May 17 '17 at 14:40
  • 1
    Also, the header file you define should not include headers it does not need to compile. There's nothing in the header that needs any of the types from 'the mighty trio' — the three most commonly used standard headers, ``, ``, `` — so they do not need to be included in the header, and arguably should not be included in the header. There's a phrase IWYU — Include What You Use — and a program to ensure that you obey that (produced by Google, originally). Your header violates IWYU. – Jonathan Leffler May 17 '17 at 14:45
  • reading your question I realized my header's guards were a copy/paste of another header. So the pre-processor didn't want to include the new .h. Probably working at 4am had something to do with that... – onlycparra Jun 03 '21 at 23:10

3 Answers3

5

You don't show that your main.c file has the two rather obvious

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

lines, is that on purpose? Otherwise this is the answer, I think.

Badda
  • 1,329
  • 2
  • 15
  • 40
unwind
  • 391,730
  • 64
  • 469
  • 606
  • Those includes are already in the header file, declaring them two times makes errors. Must I move them into main and have no includes in the header ?? – Badda May 17 '17 at 12:58
  • 2
    @Badda, you seem to have a serious misconception. *Each translation unit* -- roughly one C source file and all headers directly or indirectly `#include`d by it -- should have a declaration of every function referenced therein. For functions defined elsewhere, this is normally accomplished by including the appropriate header file. As you have presented it, your `main.c` does not do this, but it needs to do. Whether the same headers are included into other translation units is an altogether separate question. – John Bollinger May 17 '17 at 13:04
  • @JohnBollinger I understand what you are saying. But including `#include "../header/fileProcessing.h"` produces errors like `first defined here` and `multiple definition of`. Which, I think, means that the header is already included and that doing it twice is not possible. But may be I am misundersting even more than what I thought. I'd be glad to understand. Do you think that adding this and the corresponding errors to my question is relevant ? – Badda May 17 '17 at 13:11
  • 2
    @Badda, adding that `#include` directive to your `main.c` *should not* cause any error, and *does not* cause any error for me with the code you've presented (and laid out as I've inferred is required). In fact, it nicely resolves all the compiler warnings. If you observe a different result then you've omitted something relevant from your question. – John Bollinger May 17 '17 at 13:44
  • "I'll add the function's body if needed, but I have seen nowhere any clue telling that a function's body could cause an include error" So you think it can ? If so, i'll delete this question and try to ask or more relevant and precise one. – Badda May 17 '17 at 14:14
  • It's unclear to me what you're asking, @Badda. Obviously, the body of your `main()` function is causing the compiler to issue warnings. On the other hand, the body of `STLINKReadSytemCalls()` is irrelevant to those warnings. Moreover, `#include`ing the `fileProcessing.h` header you've presented into `main.c` has nothing to do with that (or any) function's body. – John Bollinger May 17 '17 at 14:20
5

As you've presented it, your main.c contains calls to two functions that have no in-scope declaration: STLINKReadSytemCalls() and printf(). That correlates with the warnings (not errors) emitted by the compiler, and it is the only thing about the code you've presented that could explain those warnings.

At this point I emphasize that

  1. The problem is what I just described: the lack of in-scope function declarations at the point where these functions are called. Your "four problems [that] might cause these errors" (only three actually presented) describe various specific avenues by which such problems sometimes arise; none of them is itself the problem.

  2. The compiler is emitting warnings, not errors. That means it accepts the code, but it cannot be certain that it did the right thing with it. In particular, it relies on the number and type of the arguments to guess the argument lists, and it guesses that the functions return int. This is not safe, but if you get lucky then it might work, or at least seem to do.

Given that the problem is lack of function declarations, the solution is, obviously, to ensure that all the needed declarations are provided, and that they are in scope where those functions are referenced. For functions defined elsewhere than in the same C source, the usual solution is to #include a header file or files containing the needed declarations. Supposing that the headers in question are written appropriately (the standard library's are, and the internal one you've presented is) that's all there is to it.

The layout of your project is not entirely clear, but it looks like you could achieve that by putting

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

at the beginning of main.c, as indeed @unwind already suggested. That change is enough to satisfy my compiler.

You have suggested that doing that causes some other kind of problem with your original code. If that's true, then it would constitute an altogether different question, and if you can't figure it out then you could consider posing it here as such. There is no hint of such a problem in this question as posed, and as an altogether separate concern, it would be inappropriate to raise that here.


As an aside, I add that I find it a bit odd (but not wrong) that your fileProcessing.h #includes the standard stdio.h, stdlib.h, and string.h headers even though it has no dependencies on any of them. As a style rule, I strongly recommend that each source file, including header files, should #include all headers required for the features they use directly, but no others. In support of that, all headers should furthermore have proper multiple-inclusion guards, as the header you present in fact does.

Thus, I would rewrite fileProcessing.h like so:

#ifndef FILEPROCESSING_H_
#define FILEPROCESSING_H_

int STLINKReadSytemCalls(void);

#endif /* FILEPROCESSING_H_ */

... and let other files handle #includeing any or all of the three aforementioned standard library headers as needed.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I will post another question, thanks for helping me focusing on what seemed to be working and what did not. I think I might have misjudged the causes of my errors and by doing so, misleaded you all by giving you irrevelant information. I do apologize and may be this question needs to be flagged. Regarding the data I gave you, I consider that your answer deserved to be accepted, as it perfectly solves the problem I was describing. – Badda May 17 '17 at 14:51
0

Probably a reuse of FILEPROCESSING_H_ symboh. Can happen with .h copy-paste