Where are declaration and definition stored? - c

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.

Related

Why is there a need to link with `printf.o` if it's already defined inside `stdio.h`?

As far as I understand when we include stdio.h the entire file is copied into the text of our program.(basically we prepend it) Then when we do a function call for printf() why does it have to be linked first?
Is it that stdio.h contains just the definitions of those functions and the compiler finds the compiled executable object file for the function that we invoke for example printf().
I've read about this in a few places but still kinda not clear.
Header files like stdio.h generally just contain a declaration that defines the name of the function, the types of its arguments, and its return value. This is enough for the compiler to generate calls to the function, but it is not a definition. The actual code that implements the function is going to be in a library (with an extension like .a or .o or .lib).
Nope. printf() is included in libc.so (this is where the printf() function resides), which is the C standard library. The compiler includes automatically -lc as option, when it calls the linker, so you don't need to add that option. Only in case you link your object files calling the linker ld directly, is when you need to include the option yourself (and some other files that form the C runtime, the linker doesn't know that you are linking a C source program, so it doesn't know what files to link with your modules, but the compiler does) See the documentation of the compiler you use, or just use the -v option when building the executable, to see the command line the compiler uses to call the linker, and you will see all the objects and libraries the compiler requires for every C program.

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.

When and how is the code for library functions added in c?

When we include the header files in C , we actually add the declaration of the functions such as the printf , scanf etc. But how does the code for the function ( the function declaration ) get added to the program ?
That's done by the process of linking. Individually compiled translation units have a way of referring to dependent names symbolically, so your code would only say "call a function with name 'printf'", and it is the job of the linking procedure to look up those symbols in one of the provided object or library files.
The standard library is usually linked against your code implicitly, so you may not be aware of the fact that you are linking your code with pre-existing library code. You would definitely be aware of this if you used your own libraries.
Note that there is no standard for linking, so you cannot generally compile one file with one compiler and another file with a different compiler and then link them together. The problem is not just to agree on how names are represented, but also on how to generate code for function calls. There are however several "informal" calling conventions and name mangling rules on popular platforms that offer a degree of interoperability.

What is the difference between include and link when linking to a library?

What does include and link REALLY do? What are the differences? And why do I need to specify both of them?
When I write #include math.h and then write -lm to compile it, what does #include math.h and -lm do respectively?
In my understanding, when linking a library, you need its .h file and its .o file. Does this suggest #include math.h means take in the .h file while -lm take in the .o file?
The reason that you need both a header (the interface description) and the library (the implementation) is that C separates the two clearer than languages like C# or Java do. One can compile a C function (e.g. by invoking gcc -c <sourcefile>) which calls library code even when the called library is not present; the header, which contains the interface description, suffices. (This is not possible with C# or Java; the assemblies resp. class files/jars must be present.) During the link stage though the library must be there, even when it's dynamic, afaik.
With C#, Java, or script languages, by contrast, the implementation contains all information necessary to define the interface. The compiler (which is not as clearly separated from the linker) looks in the jar file or the C# assembly which contain called implementations and obtains information about function signatures and types from there.
Theoretically, that information could probably be present in a library written in C as well — it's basically the debug information. But the classic C compiler (as opposed to the linker) is oblivious to libraries or object files and cannot parse them. (One should remember that the "compiler" executable you usually use to compile a C program , e.g. gcc, is a "compiler driver" which interprets the command line arguments and calls the programs which actually do stuff, e.g. the preprocessor, actual compiler and actual linker, to create the desired output.)
So in theory, if you have a properly annotated library in a known location, you could probably write a compiler which compiles a C function against it without having function declarations and type definitions; the compiler would have to produce the proper declarations. The compiler would have to know which library to parse (which corresponds to setting a C# project "Reference" in VS or having a class path and name/class correspondence in Java).
It would probably be easiest to use a well-known debugging format like stabs or dwarf and extract the interface definitions from it with a little helper program which uses the API for the debug format, extracts the information and produces a C header which is prepended to every source file. That would be the job of the compiler driver, and the actual compiler would still be oblivious to that.
It's because headers files contain only declaration and .o files (or .obj, .dll or .lib) contain definitions of methods.
If you open an .h file, you will not see the code of methods, because that is in the libraries.
One reason is commercial, because you need to publish your code and have the source code in your company. Libraries are compiled, so you could publish it.
Header files only tell compiler, what classes and methods it can find in the library.
The header files are kind of a table-of-contents plus a kind of dictionary for the compiler. It tells the compiler what the library offers and gives special values readable names.
The library file itself contains the contents.
What you are asking are entirely two different things.
Don't worry , i will explain them to you.
You use # symbol to instruct the preprocessor to include the math.h header files which internally contain the function prototypes of fabs(),ceil() etc..
And you use -lm to instruct the linker, to include the pre-compiled function definitions of fabs(),ceil() etc. functions in the exe file .
Now, you may ask why we have to explicitly link library file of math functions unlike for other functions and the answer is ,it is due to some undefined historical reasons.

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.

Resources