Why don't I have "undefined reference to"? [duplicate] - c

This question already has answers here:
Must declare function prototype in C? [duplicate]
(10 answers)
Closed 6 years ago.
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?

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.

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.

Related

Without header(stdio.h) file, how can the following code run? [duplicate]

This question already has answers here:
Why is #include <stdio.h> not required to use printf()?
(3 answers)
Closed 5 years ago.
How this following code can run without including header file for printf function?
int main(){
printf("%d",1);
return 0;}
Note: This is a hand-wavy answer that will roughly be correct. Someone else who knows the gory details (for gcc, e.g.) may enlighten both of us. Here goes:
Because in C — at least for some compilers — implicitly defined functions are fine. So it compiles it, then hands it off to the linker. It sees a reference to printf, and since the linker by default links with the C runtime library, it will resolve that symbol to the correct function.
I guess an implicit function like that will get a default signature, typically expecting to return an int. As for the arguments to the function, those can't be type checked at compile time, because the compiler doesn't know what the actual function signature is. So it will just use standard calling convention, e.g. pass arguments by registers or something like that.

Importance of function prototype (declarations) in header files [duplicate]

This question already has answers here:
Are prototypes required for all functions in C89, C90 or C99?
(6 answers)
Closed 5 years ago.
I was writing some code in a project spanning multiple *.c and *.h files (i guess I can call the *.c and *.h as modules or programs) and forgot to declare a newly created "getter" function in the header file for particular module/program. The header file was included in another module which needed access to that getter function.
Somehow the program worked fine!
I would like to know what is the importance of the declaring function prototypes in the header if the linker is able link object files to sort things out for itself. Duplicate function resolution??? This would mean that linker links by function name by matching it to what is called in function.
How does linker treat the extern variables?
C used to allow implicit declarations of functions. If a function was not declared when it was called, the compiler used the call to deduce (guess) the declaration. This deduction may be correct, or it may be wrong, and if it's wrong then that will lead to undefined behavior when you run the program.
With a proper prototype declaration the compiler doesn't have to guess.
The prototype tells the compiler the involved types (return value and arguments) of the function. Without a prototype, they are all implicitly int. This might work for some functions, but is deprecated in standard C (and disallowed starting from C99; it was common in pre-standard C), so you should always have a declared prototype for any function you call. A good compiler will warn you if you enable warnings. E.g. for gcc, always use something like -std=c11 -Wall -Wextra -pedantic (or some older C standard for -std) to get useful warnings.

Why are string functions working without including the string library?

In my code, I call functions from the string.h library (specifically, strcmp()), but I forgot to add the string library. Even without including the string library, my code compiles and runs properly as if I had included the string library.
What is happening?
A header file (e.g., string.h) only includes function declarations: that is, the return type and types and number of parameters.
The functions are defined in the C library (which is linked against your code by default), so they are are available to you whether or not you #include <string.h>. However, if you fail to #include the header file, the compiler might warn you about missing function declarations, and it can also cause problems if the return type of a function is other than int (the default for functions not otherwised declared in C).
Starting with the 1999 ISO C standard, calling a function with no visible declaration is a constraint violation, requiring a diagnostic. The diagnostic may be a non-fatal warning.
Some C compilers do not enforce the newer C99 rules by default. For example, until recently gcc's default behavior was -std=gnu89, which supports the 1989/1990 C standard with GNU-specific extensions.
Under the older rules, if you call a function with no visible declaration, an implicit declaration is created assuming that the function returns int and expects the number and types of arguments you've passed it. If that assumption is incorrect, the call's behavior is undefined. It happens that strcmp() returns an int, so if the compiler accepts the call you'll probably get away with it.
You should find out how to get your compiler to at least warn you about calls to undeclared functions. Once you've confirmed that it will do so, you should add the requires #include <string.h> to your code.
Note that the #include directive only includes the header file that declares strcmp and other standard functions, not the library. The definitions of those functions (the code that implements them) is commonly included as part of the C standard library. Linking your program to the standard library is handled by the linker, not by the compiler, and it's usually done implicitly (because you asked to compile and link a C program). (The math library, depending on the implementation, might not be linked automatically, but the implementation of the string functions almost always is.)
The string library is in fact included if you include the stdio library. But the stdio does not include the string library(not directly)
By default compiler include all necessary header file and program will successfully run.
Which Compiler you are using ?
you should use C99 compiler with -strict flags and -error flags then compiler will give you error if you call a function without including header file..
Error will look like this
implicit declaration of strcmp() found

Relevance of specifying an empty parameter list in C with void [duplicate]

This question already has answers here:
Is it better to use C void arguments "void foo(void)" or not "void foo()"? [duplicate]
(6 answers)
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 8 years ago.
Having done most of my dev deeds in C++ and C#, I find the habit in C of specifying an empty parameter list with "void" a bit peculiar, but seeing it in "trustworthy sources" makes me assume it's required-ish. The question is why?
To clarify, in for instance Visual Studio, I cannot with any combination of enabled C compiler switches, and disabled C++ compiler switches, get even as much as a compiler warning when writing this:
void foo_bar();
Then, what is it that makes it necessary-ish to instead declare it with this:
void foo_bar(void);
Is it just old C standardese that is lingering that is not needed with later C standards?
Backstory:
When declaring functions in C (any symbol actually) you need declare everything in the proper order (declare a function before using it) otherwise you'll get errors regarding undefined symbols.
Forward declaration of functions allows you to accomplish this by declaring only the function signature (without the body). This allows the compiler to identify function names (symbols) and later use them before they are completely defined.
When using forward declarations to export the publicly accessible functions of a library (in your public header files) you will declare the entire signature so that users of your library will know what parameters are expected.
When using forward declarations for your own internal use you (sometimes) won't need to declare the entire signature of the function, only the return type and name will suffice -- no parameters. Only when you finally define the function will you specify the parameter list.
Direct answer:
Yes it's just old C standardese and nothing more. Because the same C standardese says that empty brackets means an unknown number of parameters (not necessarily 0).
Related reading:
This question I've asked some time ago tries to fathom (like you) the utility of declaring functions with "an unknown number of parameters" -- apparently in a very misconstrued way.

C program is running without including Header files? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C program without header
I have been studying C for a long time . but one thing that bothering me is that , today I made a C program and forget to include the stdio.h and conio.h header files I saved the file as kc.c ? when I compiled and run this .c file the output was as I was expecting to be.
but how can a C program could run without using the standard header file?
or I am not aware with the concepts that I am missing hear?
EDIT: the program
int main()
{
int i=12,j=34;
int *pa=&i,*pb=&j;
printf("the value of i and j is %d %d respectively ",*pa,*pb);
getch();
return 0;
}
because I have used the printf() function of STDIO.H header here ,but without including it how can It got compiled and run successfully?
The compiler is allowed to make things work, but is under no obligation to do so.
You are supposed to declare all variable argument list functions before using them; not declaring printf() properly leads to undefined behaviour (and one valid undefined behaviour is to work as expected).
You should be getting warnings about the undeclared functions if you compile in C99 mode (but Turbo C probably doesn't have a C99 mode).
Nit-picking:
[H]ow can a C program could run without using the standard header file?
All programs run without using any headers whatsoever. However, most programs are compiled using the standard headers to declare the standard functions, and the better programs ensure that all functions are declared before they are used (or are defined as static functions before they are used).
C99 requires this, though many compilers will allow errant programs to compile. However, the compilation should produce a diagnostic; the diagnostic may or may not lead to the compilation failing. In practice, it usually doesn't cause the compilation to fail, but it could and with some compilers (GCC, for example) you can force the compiler's hand (e.g. with GCC's -Werror=missing-prototypes -Werror=old-style-definition options).
When the language standard being applied pre-dates ISO C99, C does not require a function to be declared or defined before it is referenced.
However when the compiler encounters such a function call, it simply assumes that the function returns an int and that it takes an indeterminate number and type of parameters. This is called am implicit declaration. If you later declare the function, or call it with a different number of parameters or incompatible parameters, you may get a warning in some compilers that the second call does not match declaration implied by the first, but the ISO C89 standard treats the function as variadic [like printf()] where any number and type of parameters are allowed.
Moreover if the actual return value is not an int, any return value accepted and processed may not make much sense one way or another.
It is bad form to rely on an implicit declaration, and most compilers would issue a warning. If your compiler did not, you need to increase the warning level; those diagnostics are there to help improve your code quality. If you simply ignored the warning (any warning for that matter), then you shouldn't!
In C++ the rules are tighter and failure to declare or define a function before referencing it is an error, since it is necessary to allow function overloading.
A header file is nothing more than a listing of constants, preprocessor macros and function prototypes. The function prototypes tell C what arguments each function takes.
If the compiler sees a function being used without a corresponding prototype or function definition, it generates an implicit declaration of the form int func(). Since C functions are linked solely by name and not by function signature (as is the case with C++), the linker later locates the function definitions in the standard library.

Resources