removing reference to printf built-in function - c

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.

Related

Is it possible to call a function in a shared library that has not been declared?

The short version:
I'm trying to use a function in a shared library that hasn't been declared in a header file. Is it possible? If so, how?
The long version:
I'm trying to use GNU readline-7.0 as a shared library. Unfortunately it will echo input by default unless you turn it off with an api call. Sadly this api call wasn't declared in their header, because someone forgot. see details here Note: I can't update to a newer readline, so I'm stuck with this library. How do I use this undeclared function?
As noted in the linked bug, there is no external declaration in the header file even though the function exists in the implementation.
The link also shows the fix with the added declaration:
extern int rl_tty_set_echoing PARAMS((int));
So you can add this in your code right after #include <readline.h>
The sort answer is yes!!!
Just use the library -ldl with function dlopen(3), etc. This library allows you to load a shared object and search for identifiers that you know nothing about. Of course, the static typing nature of C forces to declare the interface of those functions with a prototype, so once you get a (void *) to the object you can cast it to something like int (*t)() and jump to it with a t(); call.
In the manual page you will get the details, dlopen allows you to search a shared object for symbols passed as strings. It returns pointers to the places those identifiers have been loaded in memory. You can even do this with your own program.
On the other hand, this is a feature of ELF shared loaded modules. If you are running a.out executables or otherwise, it is now waranteed that you'll have a dlopen(3) library for it, or that it will work that way.

Where are declaration and definition stored?

For a predefined function where are the declaration and definition stored?
And is the declaration stored in libraries? If so, then why it is named library function?
This is an imprecise question. The best answers we can give are:
The declaration of standard library functions can best be thought of as being stored in their header files.
Depending on how you want to think about it, the definition of standard library files is either in the source files for those libraries (which may be invisible to you, a trade secret of your compiler vendor), or in the library files themselves (.a, .so, .lib, or .dll).
These days, knowledge of standard library functions is typically built in to the compiler, also. For example, if I write the old classic int main() { printf("Hello, world!\n"); }, but without any #include directives, my compiler says, "warning: implicitly declaring library function 'printf'" and "include the header <stdio.h>".
There are two sides of this story:
The code that calls a library/external function: The compiler generates a reference in your compiled module that encodes which function prototype you expect to exist elsewhere.
The pre-compiled library files against which your code must be linked: A library file contains both the coded prototypes of its functions as well as the actual compiled binary (i.e. the definition/implementation) for these function.
When your code uses an external function, the compiler generates a reference to this function that it assumes will be resolved later during the linking phase.
During the linking process lists of function references are build up. The linker expects to find the 'definition'/implementation of each of the used references.
The header file contains the declaration of built-in functions and the library contains the definition of the functions.
The name library is because, in my opinion, as the actual library which contains books, these libraries contain the classes, functions, variables etc.

Why do some system libraries require a -l option while others do not?

I recently took a class where we used pthreads and when compiling we were told to add -lpthread. But how come when using other #include <> statements for system header files, it seems that the linking of the object implementation code happens automatically? For example, if I just want to get the header file #include <stdio.h>, I don't need a -l option in compilation, the linking of that .o implementation file file just happens.
For this file
#include <stdio.h>
int main() {
return 0;
}
run
gcc -v -o simple simple.c
and you will see what, actually, gcc does. You will see that it links with libraries behind your back. This is why you don't specify system libraries explicitly.
Basic Answer: -lpthreads tells the compiler/linker to link to the pthreads library.
Longer answer
Headers tell the compiler that a certain function is going to be available (sometimes that function is defined in the header, perhaps inline) when the code is later linked. So the compiler marks the function essentially available but later during the linking phase the linker has to connect the function call to an actual function. A lot of function in the system headers are part of the "C Runtime Library" your linker automatically uses but others are provided by external libraries (such as pthreads). In the case where it is provided by an external library you have to use the '-lxxx' so the compiler/linker knows which external library to include in the process so it gets the address of the functions correctly.
Hope that helps
A C header file does not contain the implementations of the functions. It only contains function prototypes, so that the compiler could generate proper function calls.
The actual implementation is stored in a library. The most commonly used functions (such as printf and malloc) are implemented in the Standard C Library (LibC), which is implicitly linked to any executable file unless you request not to link it. The threads support is implemented in a separate library that has to be linked explicitly by passing the -pthread option to the linker.
NB: You can pass the option -pthread to the compiler that will also link the appropriate library.
The compiler links the standard C library libc.a implicitly so a -lc argument is not necessary. Pthreads is a system library but not a part of the C standard library, so must be explicitly linked.
If you were to specify -nolibc you would then need to explicitly link libc (or some alternative C library).
If all system libraries were linked implicitly, gcc would have to be have a different implementation for each system (for example pthreads is not a system library on Windows), and if a system introduced a new library, gcc would have to change in lock step. Moreover the link time would increase as each library were searched in some unknown sequence to resolve symbols. The C standard library is the one library the compiler can rely on to be provided in any particular implementation, so implicit linking is generally safe and a simple convenience.
Some library files are are searched by default, simply for convenience, basically the C standard library. Linkers have options to disable this convenience and have no default libraries (for if you are doing something unusual and don't want them). Non-default libraries, you have to tell linker to use them.
There could be a mechanism to tell what libraries are needed in the source code (include files are plain text which is just "copy-pasted" at #include line), there's no technical difficulty. But there just isn't (as far as I know, not even as non-standard compiler extension).
There are some solutions to the problem though, such as pkg-config for unixy platforms, which tackle the problem of include and library files by providing the compiler and linker options for a library easily.
the -l option is for linking against an external library in this case libpthread, against system libraries is linked by default
http://www.network-theory.co.uk/docs/gccintro/gccintro_17.html
C++: How to add external libraries

Call function in shared library but not declaration in header files

I am doing some implementation about calling function of shared library via Java to JNI.
And JNI is implemented by C code.
Here is my question.
There is a function named ABC() in shared library.
This function is not be declared in header files.
BUT with NDK build, it can be successful and this function also can work fine.
It's very confusing.
Why? why can it be built by NDK and why can it be called without any exception?
Thank you for answering:)
There are two possibilities here.
The file using the function may contain its own declaration of the function. (Declarations are not required to be only in header files.)
If you use a function without declaring it, the compiler may provide a default declaration. This is not part of modern C, but compilers may use old standards or be unduly lax in this regard. The default declaration is a function of the type int SomeName(). Such implicit declarations automatically have external linkage, which means the name will be matched to the definition of the function when the library is linked in.
If the latter is the case, you would be well advised to enable additional switches to tell the compiler to issue more warning messages and to use a modern language standard (such as C 2011), at least when developing new code.
Using a routine that is in a shared library but is not declared in its header is inadvisable. Such routines are often intended only for internal use of the library, and they may change or vanish in future versions of the library. So code using them would break; it would not be compatible with the new versions of the library.

C programming directives #include<stdio.h> printf

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.

Resources