2

I faced a similar problem in my (big) project.

//# include <string.h> // not included

void foo(char * str, const char * delim)
{
    char * tok = strtok(str, delim); 
    // warning ^ "assignement makes pointer from integer without a cast"

    // [...]
}

The answer (just add #include <string.h> to have the prototype of strtok) solved the issue indeed.

However, due to my poor compiler/linker knowledge, I fail to understand how the process accepts a function that have not been prototyped. I'd rather expected the error undefined reference to function 'strtok' which is typical when you forget to include the right header.

[EDIT] I understand why this question has been marked as duplicate but I do think it is different : I am aware of "good practice" regarding includes, I am just wondering about compiler's behavior. However I admit that I can found (part of) an answer to my question in this post: Are prototypes required for all functions in C89, C90 or C99? or this one: Must declare function prototype in C?

Community
  • 1
  • 1
n0p
  • 3,399
  • 2
  • 29
  • 50
  • 1
    Short answer: You will get an error if you compile the code as C99 or later. Add the gcc flag `-std=c11` or `-std=c99`. – Klas Lindbäck Sep 05 '16 at 13:59
  • The compiler never will "throw" (whatever that means) or report such an error. That is the linker. And regardless of the "must": you definitively **should**. Any halfway modern coding standard of the last 20 years requires that. – too honest for this site Sep 05 '16 at 14:09
  • @Olaf Fixed (this is already a clue about the answer to my post actually). Any chance to revert the "duplicate" mark following my edit ? – n0p Sep 05 '16 at 14:19
  • I don't see this is **not** a dup, so I will not vote to re-open. If you want to know more about that in detail, just read the standard or a good C book, (on this subject **only** an older one might even be better). Otherwise just enable warnings, use a modern C compiler which supports **at least** C99 so you get warnings, enable all other recommended warnings and ... **use prototypes!** – too honest for this site Sep 05 '16 at 14:33

2 Answers2

3

While linking your binary, unless explicitly mentioned, your binary is linked with the default C standard library (glibc, for example) anyways, where the function is defined.

So, when you miss the header file containing the declaration, you end up with the warning (in case the function prototype has a mismatchnote) but during linking time, due to the presence of the default C library, the program is successfully linked anyway.

FWIW, according to C11, support for implicit function declaration has been dropped but most compilers support the bad behavior to keep the backward compatibility for the legacy code.


NOTE:

Implicit function declaration: Earlier, (before C99, AFAIK), the standard did not mandate for a function to have the forward declaration. In case, a function would have been used without a forward declaration, it was assumed to return int and accept any number of incoming parameters.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • I'd say "*bad* behavior" is a bit strong - it's *different* behavior. With legacy code, not requiring prototypes is a critical language feature because it's not safe to just add prototypes for functions that were coded without them as function arguments are treated differently - see http://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls – Andrew Henle Sep 05 '16 at 13:55
  • @AndrewHenle Sorry, but I did not get the point. Isn't there variadic functions to achieve the same while conforming to the standard? What am I missing? – Sourav Ghosh Sep 05 '16 at 14:42
1

Because gcc automatically links your code with the C library. The "undefined reference to function" error is typically issued by the linker when it couldn't resolve a symbol and that only occurs if the symbol couldn't be found in any of the libraries linked (the order of linking might also matter). But the C library is linked by default -- it's as if you linked it with -lc. So, you don't get that error.

If you tell gcc to not link the C library using -nostdlib then you'll see the error you expected:

$ gcc -nostdlib file.c

On the other hand, you should always provide prototypes for functions.

You may be interested in other similar linker options such as -nodefaultlibs, nostartfiles etc which you can find in gcc's manual.

P.P
  • 117,907
  • 20
  • 175
  • 238