C programming directives #include<stdio.h> printf - c

I have that simple hello world program.
First row it says #include <stdio.h>.
I googled it and it tells basically the preprocessor to define the functions for input/output.
First question:
I read that the actually code of the function first compiled to an object file. So if I say #include <foo.bar> it automatically linkes that object file?
Second question:
When I removed the include, the program still works... I mean the printf statement... why?

printf() is located in standard C library and linker links standard library to your program.
So any standard functions will not be any linking problems.
If you compile the program without #include<stdio.h> using gcc you will get the warning.

In some older compilers without including the headers for standard library function your code will not compile.
In some modern compilers the standard library is linked by default.
If the header for any library used is not included a warning is issued like the following:
[Warning] implicit declaration of function 'printf' [-Wimplicit-function-declaration]
For non standard library function you must have to link it with your program . Do not forget to include its header.

Because few compiler includes those files and libraries by default!

The printf function is defined in the standard C library, which your compiler links automatically to your program, unless told otherwise. The header file only has the function declaration so removing the include directive does not make the function unavailable.

Related

removing reference to printf built-in function

I faced a stack overflow problem in my STM32F4xx project. It came out that printf is the cause. FreeRTOS support suggests to use printf-stdarg.c instead.
I have removed all stdio.h includes in my project. It complains of "incompatible implicit declaration of built-in function 'printf'" but compiles OK meaning the linker has used the built-in library.
My question is how to how to prevent linker (gcc) from using built-in printf/sprintf function.
If you linked printf-stdarg.c into your executable, then that function will be called instead of the system defined printf. The functions in standard library are weak symbols, which means you can define a function of the same name which will override the system function.
Removing #include <stdio.h> doesn't prevent the system library from being linked in. It just gets rid of the function prototypes your code needs.
Put the includes back in your code and link with printf-stdarg.c, and your code will use those functions.

C compiles with an undefined symbol

I am using an older version of the Diab C compiler.
In my code I have taken a function name and redefined it as a function pointer with the same signature. Before making this change the code worked. After the change it made it caused the embedded system to lock up.
The function pointer was declared extern in a header, defined in one .c file, and used in another .c file. When it was called from the second .c file it would cause the system to lock up. When I attempted to add debug information using sprintf it finally told me that it was an undefined symbol. I realized that the header file was was not included in the second .c file. When I #included it everything compiled and worked correctly.
My question is, is there some C rule that allowed the compiler to deduce the function signature even though the symbol was undefined at the call location? To my understanding there should have been an error long before I made any changes.
If no declaration is available, the compiler uses a default declaration of a function taking an unknown number of arguments and returning an int. If you turn up compiler warnings (eg -Wall -Wextra -Werror with gcc, check the documentation for your compiler), you should get a compile time warning.
Most likely, the code at first worked because it was compiled in the C89 or similar mode. The C standard from 1989 allows calling functions without first declaring them.
When you changed the code to use a pointer but didn't include the declaration of the pointer, the compiler assumed that your pointer was in fact a function and generated code to call into the pointer, as if the pointer had executable code inside. As the result, the program understandably stopped working.
What you should do is enable all possible warnings (for gcc: -Wall, -Wextra and make sure optimization is enabled (-O2 is good) because it enables code analysis), especially for calling functions without prototypes. A better thing might be to switch the compiler into the C99 mode (-std=c99 in gcc) or switch to a C99 compiler. The C standard from 1999 prohibits calling functions without prototypes and comes with some useful features absent in C89.

Why am I able to compile and run C programs without including header files?

I have tested this fact on Turbo C++ 3.0, VC++ 2008 express and Borland C++ 6.
If I add a C program with *.C extension to the project, I am able to compile and run the program without including header files. But in this case, some functions (like sqrt(), etc..) are returning erroneous values.
If I add a C program with *.CPP extension to the project, I am not able to compile and run the program without including header files.
Why?
In C, when the compiler does not find the definition of a function, it assumes it's an external function returning an integer. So the code compiles, and if the linker then finds a function with corresponding name it will run as well. But possibly with unexpected results.
By default in C function return type is int, and even if prototype not declared you'll be able to use, for example, libc functions. Of course, if its return value not int, you've got erroneous values.
C++ are more stricter and disallow this.
Also, gcc implements some functions as built-ins. You can try compiling with -fno-builtin options, if you use it.
If you don't provide a declaration for a function, C makes a guess at it. This guess is almost always wrong, hence your "erroneous values". C++ doesn't do this.
The C++ standard requires a function prototype to be seen before a function is used.
C does not have this requirement. If a C compiler sees an undeclared function it creates an implicit declaration assuming that the function returns int. If the function doesn't really return int unpredictable things will happen, as you are seeing with sqrt.

Detect undefined symbols in C header file

Suposse I coded a C library which provides a bunch of "public" functions, declared in a mylib.h header file. Those functions are supposedly implemented in (say) a mylib.c file which is compiled to a (say) static lib mylib.c -> mylib.o -> mylib.a.
Is there some way to detect that I forgot to provide the implementation of some declared function in mylib.h? (Yes, I know about unit testing, good practices, etc - and, yes, I understand the meaning of a plain function declaration in C).
Suppose mylib.h declares a void func1(); and this function was not coded in the provided library. This will trigger an error only if the linker needs to use that function. Otherwise, it will compile ok and even without warnings - AFAIK. Is there a way (perhaps compiler dependent) to trigger a warning for declared but not implemented functions, or there is any other way to deal with this issue?
BTW: nm -u lists not all undefined declared functions, but only those "used" by the library, i.e., those functions that will trigger an error in the linking phase if not declared somewhere. (Which makes sense, the library object file does not know about header files, of course.)
Basically, the most reliable way is to have a program (or possibly a series of programs) which formally exercise each and every one of the functions. If one of the programs fails to link because of a missing symbol, you've goofed.
I suppose you could try to do something by editing a copy of the header into a source file (as in, file ending .c), converting the function declarations into dummy function definitions:
Original:
extern int somefunc(void);
Revised:
extern int somefunc(void){}
Then compile the modified source with minimum warnings - and ignore anything to do with "function that is supposed to return a value doesn't". Then compare the defined symbols in the object file from the revised source with the defined symbols in the library (using nm -g on Unix-like systems). Anything present in the object file that isn't present in the library is missing and should be supplied.
Note: if your header includes other headers of your own which define functions, you need to process all of those. If your header includes standard headers such as <stdio.h>, then clearly you won't be defining functions such as fopen() or printf() in the ordinary course of events. So, choose the headers you reprocess into source code carefully.
There's no easy way.
For example, you can analyse the output of clang -Xclang -ast-print-xml or gcc-xml and filter out declarations with no implementations for a given .h file.
You could grep for signatures of exported function in both .h and .c, and compare the lists.
Use wc -l for counting matches, Both numbers should be equal.
Another thought, just came to my mind. It is ihmo not possible to handle it using compiler. it is not always the case, that function declares in mylib.h is implemented in mylib.c
Is there some way to detect that I forgot to provide the implementation of some declared function in mylib.h?
Write the implementation first, then worry about header contents -- because that way, it can be flagged.

Compiling with header files

Why do I have to specifically compile a C source file with:
gcc prog.c -lm
even when I have already included the specific header file with:
#include <math.h>
The #include file tells the compiler how a function looks like, as in what type it returns, how many parameters of what types it takes, but it doesn't tell the compiler the contents.
The -lm flag includes that actual math library which contains the code for the functions to be called.
It works the same way with printf(), fread() and other standard functions. When you include stdio.h, you don't actually include the code of the function but the definitions. Because the C library is implicitly linked without you having to do anything about that, you don't notice it.
Because you need to inform the compiler which math library to link with, nothing to do with the math.h inclusion.
Similarly to your own code, which should have header files (.h) for function declarations and source files (.c) for function definitions, the code for the math library is in two parts. The header file, which you include, contains the function declarations:
double sqrt(double n);
However, it doesn't contain anything about how these functions work. This code is in a separate file which you have to link in, similarly to how you link different source files to create an application.
Because in C, there is technically absoultely no connection between the header file and the library. There can be more header files than libraries, or the other way round. It's just a matter of convention (and of course it makes some sense) to have a 1:1 relation in most cases.

Resources