Error for ‘implicit function declaration’ Warning in C

“A young man is smoking one cigarette after each other without a pause. An elderly woman observes that and says: “Young man, you are smoking like crazy! Don’t you know that there is a warning on each cigarette package that this can kill you?” The young man finishes his cigarette, looks at the elderly person and says: “Yes, I know. But look, I’m a programmer, and it is only a warning.”

I don’t smoke, and I do pay attention to warnings :-). I always try to keep my source code free of compiler warnings. And I always pay special attention to the following on:

implicit declaration of function

implicit declaration of function

So what does the gcc warning ‘implicit declaration of function’ mean (other compiler report a ‘implicit parameter declaration’)? Basically it means that the compiler has found a call to function for which he does not have a prototype. For the case it missed a declaration like this:

 
errorCode_t calcMatrix(matrix_t *m, double weight);

Either because I did not provide a ‘forward declaration’ of it or I missed to include the header file with that declaration, or that declaration is missing in the header file.

Without knowing the interface, the compiler has to assume (implicitly) the interface from the actual parameters used, and that the function returns an int. So the compiler has to assume according to the rules:

int calcMatrix(int*, int); 

Which of course is wrong in many ways: not only the parameter 3 is not converted to a double, it means that the wrong size (int vs. double) is assumed. If that parameter is passed on the stack it will result in a stack space mismatch, so overall very bad. It might ‘work’ if the types by chance match the actual implementation or will be less of a runtime problem if parameters and return values are passed in registers. Still, it is clearly wrong and bad, bad, bad. It might be only a warning if the linker does not find that symbol (calcMatrix in this case) somewhere, so if you do not pay attention to warnings, your application might crash or behave in wrong way.

Such an ‘implicit declaration’ is really an oversight or error by the programmer, because the C compiler needs to know about the types of the parameters and return value to correctly allocate them on the stack. Unfortunately in C this is not an error but a warning (for legacy reasons, to be able to compile old non-compliant code). The good news is that compiling such a thing with in C++ will produce an error, another good reason to compile plain C code with C++ mode.

The other good news is that every C compiler usually has an option to turn this warning into an error (what I recommend if you are not paying attention to warnings). From the gcc help page:

-Werror-implicit-function-declarationGive a warning (or error) whenever a function is used before being declared. The form -Wno-error-implicit-function-declaration is not supported. This warning is enabled by -Wall (as a warning, not an error).

With this option added to the compiler settings it gets flagged as an error:

error for implicit declaration

Problem solved.

Happy warning 🙂

Links

18 thoughts on “Error for ‘implicit function declaration’ Warning in C

  1. This is such an easy way to avoid such a nasty error. This can stop the entire program even running, let alone running properly. Thanks Erich, we all need to do this- at least.
    (IMO -Werror is even better)

    Liked by 1 person

  2. A wise old programmer told me years ago: “Amateurs fix errors. Professionals fix warnings.”

    Since then, I only work with code that has no warnings – I’ve seen a number of people who get complacent when have warnings they (think they) understand and don’t notice additional ones popping up. I’ve had a number of employees push back on this only to discover that when we went through the warnings, we found some pretty big problems that would crop up during execution.

    If you don’t see “Build Finished. 0 errors, 0 warnings.” don’t try to see if your code works.

    Liked by 1 person

    • I have seen developers building projects with literally hundreds of warnings. When I asked the say was “oh, they are all ok”. Maybe a few, but they could have been easily fixed. When going through the list together there were very serious ones in there too (like using variables without having initialized them, not returning a value in all paths, etc). Pretty bad.

      Liked by 1 person

      • That could actually make a good separate blog entry/article on its own: “Prudent usage of warnings: when to ignore them and when to addrress them”, or something like that 😉

        I can see scenarios when legacy code (once being compiled without problems) gets its way into a modern code base and produces (due to newer compiler or stricter policies) warnings.

        So, in this case there is nobody to blame or accuse of carelesness.

        The original developer/maintainer did a good job to the best of her knowledge and tools available at the time. The new developer (or rather integrator) made a right decision to re-use something existing rather than rewriting from scratch.

        And still there are warnings in the code base! If you dare to touch them – you are responsible for making sure you didn’t break things (of course there are no unit tests providing regression check in that old code base).

        Dilema of a sort, if you ask me.

        Like

        • Yes, it can be a dilemma. Take the risk to ‘fix’ it with the potential to break something else.
          I had the bad experience with fixing a real bug which was flagged by a warning. Only to break the system that way. Because that bug did ‘fix’ another issue. With one issue fixed, the other was not ‘covered’ any more and caused the system to fail :-(.
          Lesson learned: fixing an issue does not make a system automatically a better system.

          Like

  3. Hi Erich,
    many thanks for this post… I’ve a vague idea about who triggers you this topic: )))
    I’m always surprised by the assumption that the user does, while 90% of the time the compiler takes a different decision
    🙃

    Liked by 1 person

    • Your vague idea might be correct ;-).
      I’m not that much surprised by the compiler. But probably it is because I wrote C and C++ compilers, both front and back ends. So this might let me think like a compiler 🙂

      Liked by 1 person

  4. Hello Mr. Styger,

    Thank you for the relevant write up (I wish more people bothered to look deeper into real reasons behind such warnings).

    Could you elaborate on:
    ” … Unfortunately in C this is not an error but a warning (for legacy reasons, to be able to compile old non-compliant code). ..”?
    Could you give an example of legacy code that is worth reusing rather than refactoring and requires -Werror-implicit-function-declaration to remain a warning, not an error?

    Regards

    Like

    • Of course refactoring is the preferred choice: but there are cases where for certification reasons your are not allowed to changed the source code, so you cannot touch it.
      I did read about the early Linux code not fully compliant (not verified), so if you build the kernel for yourself you might not mess up with changing the kernel sources and instead just let it compile (and assume and hope that it will work that way). Again, it is just for legacy and this is how it has been defined for the compiler to handle it. C++ closed that gap.

      Like

      • Ok, clear. I thought you have particular piece of code in mind.

        These things get often refactored away and disappearing more and more (especially if recognized as a source of a bigger problem).

        They are still interesting for academic purposes, though, as well as for discussions like: “Should we drop certain compiler feature nobody uses anymore, or keep it because codebase X is way too important to touch”. This legacy thing fascinates me a lot.

        Thank you once again for bringing this topic up.

        Liked by 1 person

      • Hey Erich,

        I think you’re reading too much into this and trying to find a logical reason for something that’s a whole bunch simpler.

        When Kernighan & Ritchie defined the C language, they considered calling a method without a prototype or a prototype that doesn’t match something that warranted a “warning” not an “error”. If calls to the actual method provide the right parameters then the application will run fine and there’s no need for throwing an error (hence the “warning”). You can debate the wisdom of this.

        Personally, if I were in the situation where I was calling legacy code that I could not change, I would create my own header file with correct prototypes so that the warning doesn’t come up if I am calling the methods with the incorrect parameters.

        I just reviewed my copy of “The C Programming Language” 2nd edition and there is no discussion as to why missing or incorrect prototypes are “warnings” and not “errors”.

        myke

        Liked by 1 person

        • To my knowledge that warning came into the play with the first ANSI standard for C. K&R did not bother with that one. But when the working group had to define the standard, I imagine that they wanted to give that one an error class and not only a warning. But at that time there was too much legacy code around which would not have been compileable with an error, thus the warning. At least I remember that the discussion when I wrote the C/C++ parser.

          Like

        • Hi Erich,

          This is interesting as it appears I got access to more cutting edge development tools than was out in the mainstream while I was at the University of Waterloo.

          I started using C in the summer of 1984 in Prof. Michael Malcolm’s (later of Kaleidescape) class with his custom compiler which definitely had function prototypes (I still have the class notes documenting the language) and he definitely required them in our code (marks would be taken off if they weren’t present). The next year I did courses with SGI workstations and PDP/11-780s that also had function prototypes with their Watcom C compilers (which I guess were product prototypes at the time as they didn’t go out into the market for a few years after I graduated).

          I never thought too much about it because I then worked at IBM where I did PL/S programming for five years or so before going to ANSI compatible Microsoft C and I just went along assuming that function prototypes were always part of the language.

          Thank you for the education – I suspect that it’s more than just a quirk of fate that the tools I worked with at university had this feature. I would be willing to bet that there were a fair number of “C” compilers that had function prototypes (along with other variations of the language) which lead to the specification of “C” as an ANSI standard.

          myke

          Liked by 1 person

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.