Implicit declaration of functions regardless of header include and ifndef

10,758

Solution 1

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.

Solution 2

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.

Share:
10,758
Badda
Author by

Badda

Student in computer science so far. Wishing to help as much (or even more) as I have been helped.

Updated on August 30, 2022

Comments

  • Badda
    Badda over 1 year

    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.

    • Lundin
      Lundin almost 7 years
      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.
    • Badda
      Badda almost 7 years
      @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 ?
    • Jonathan Leffler
      Jonathan Leffler almost 7 years
      Note What are the benefits of a relative path such as "../include/header.h" for a header? Generally, you're best off avoiding the .. notation in the source files including a header.
    • Jonathan Leffler
      Jonathan Leffler almost 7 years
      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, <stdio.h>, <stdlib.h>, <string.h> — 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.
    • onlycparra
      onlycparra almost 3 years
      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...
  • Badda
    Badda almost 7 years
    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 ??
  • John Bollinger
    John Bollinger almost 7 years
    @Badda, you seem to have a serious misconception. Each translation unit -- roughly one C source file and all headers directly or indirectly #included 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.
  • Badda
    Badda almost 7 years
    @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 ?
  • John Bollinger
    John Bollinger almost 7 years
    @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.
  • Badda
    Badda almost 7 years
    "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.
  • John Bollinger
    John Bollinger almost 7 years
    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, #includeing the fileProcessing.h header you've presented into main.c has nothing to do with that (or any) function's body.
  • Badda
    Badda almost 7 years
    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.
  • Armali
    Armali about 5 years
    Use correct spelling, punctuation, and grammar to the best of your ability.