I knew that header files contain declarations of functions and variables which help during compilation time whether the entered parameters are valid or not.
Are all the library functions linked by default?
//#include<stdio.h>
//#include<math.h>
int main()
{
printf("Hello\n");
double d;
d=sqrt(64);
printf("%lf",d);
return 0;
}
Compiles and produces few warnings as expected
Output
Hello
8.000000
It works!
Are all the library functions linked by default?
Most linkers from C toolchain link stdlib by default unless you disable this behaviour with a flag for example -nodefaultlibs or -nostdlibs in gcc.
Are all the library functions linked by default?
Not all, but standard library functions are usually linked by default by linkers.
Related
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
How does a compiler find out which dynamic link library will be used in my code, if I only include headers-files, where is not describe it?
#include <stdio.h>
void main()
{
printf("Hello world\n");
}
There is I only include
stdio.h
and my code is used
printf function
How it is known, in headers-files prototypes , macros and constant are described, but nothing about in which file "printf" is implement. How does then it works?
When you compile a runnable executable, you don't just specify the source code, but also a list of libraries from which undefined references are looked up. With the C standard library, this happens implicitly (unless you tell GCC -nostdinc), so you may not have been consciously aware of this.
The libraries are only consumed by the linker, not the compiler. The linker locates all the undefined references in the libraries. If the library is a static one, the linker just adds the actual machine code to your final executable. On the other hand, if the library is a shared one, the linker only records the name (and version?) of the library in the executable's header. It is then the job of the loader to find appropriate libraries at load time and resolve the missing dependencies on the fly.
On Linux, you can use ldd to list the load-time dependencies of a dynamically linked executable, e.g. try ldd /bin/ls. (On MacOS, you can use otool -L for the same purpose.)
As others have answered, the standard c library is implicitly linked. If you are using gcc you can use the -Wl,--trace option to see what the linker is doing.
I tested your example code:
gcc -Wl,--trace main.c
Gives:
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o
/tmp/ccCjfUFN.o
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc_s.so)
/lib/x86_64-linux-gnu/libc.so.6
(/usr/lib/x86_64-linux-gnu/libc_nonshared.a)elf-init.oS
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-linux-gnu/4.6/libgcc_s.so)
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
This shows that the linker is using libc.so (and also ld-linux.so).
The library glibc is linked by default by GCC. There is no need to mention -l library when you are building your executable. Hence you find that the functions printf and others which are a part of glibc do not need any linking exclusively.
Technically your compiler does not figure out which libraries will be used. The linker (commonly ld) does this. The header files only tell the compiler what interface your library functions use and leaves it up to the linker to figure out where they are.
A source file goes a long path until it becomes an executable. Commonly
source.c -[preprocess]> source.i -[compile]> source.s -[assemble]> source.o -[link]> a.out
When you invoke cc source.c all those steps are done transparently for you in one go and the standard libraries (commonly libc.so) and executable loader (commonly crt0.o) are linked together.
Any additional libraries have to be passed as additional linker flags i.e. -lpthread.
I would say that depends on IDE or the compiler and system. Header file just contains interface information like name of function parameters it expects any attributes others and that's how compiler first convert your code to an intermediate object file.
After that comes linking where in code for printf is getting added to the executable either through static library or dynamic library.
Functions and other facilities like STL are part of C/C++ so they are either delivered by compiler or system. e.g on Solaris there is no debug version of C library unless you are using gcc. But on Visual Studio you have debug version msvcrt.dll and you can also link C library statically.
In short the answer is that code for printf and other functions in C library are added by compiler at link time.
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.
Scenario 1:
I want to link an new library (libA) into my program, libA was built using gcc with -std=gnu99 flag, while the current libraries of my program were built without that option (and let's assume gcc uses -std=gnu89 by default).
Scenario 2:
libB was built with some preprocessor flags like "-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED" to enable XPG4 features, e.g. msg_control member of struct msghdr. While libC wasn't built without those preprocessor flags, then it's linked against libB.
Is it wrong to link libraries built with different preprocessor flags or C standards ?
My concern is mainly about structure definitions mismatch.
Thanks.
Scenario 1 is completely safe for you. std= option in GCC checks code for compatibility with standard, but has nothing to do with ABI, so you may feel free to combine precompiled code with different std options.
Scenario 2 may be unsafe. I will put here just one simple example, real cases may be much more tricky.
Consider, that you have some function, like:
#ifdef MYDEF
int foo(int x) { ... }
#else
int foo(float x) { ... }
#endif
And you compile a.o with -DMYDEF and b.o without, and function bar from a.o calls function foo in b.o. Next you link it together and everything seems to be fine. Then everything fails in runtime and you may have very hard time debugging why are you passing int from one module, while expecting float on callee side.
Some more tricky cases may include conditionally defined structure fields, calling conventions, global variable sizes.
P.S. Assuming all your sources are written in the same language, varying only std options and macro definitions. Combining C and C++ code is really tricky sometimes, agree with Mikhail.
The few times I have encountered structure definition mismatch was when combining C and C++ code, in these cases there was a clear warning that something terrible was happening.
Something like
/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o
See that question.
How can I compile my C source files without needing to put a main function within them?
I get an error for the .cfiles that have no main function and don't want to have to add the main function just for compilation.
On GCC, the -c switch is what you want.
-c means "compile, don't link", and you get a name.o output file.
Suppose you have hello.c:
#include<stdio.h>
#include<stdlib.h>
_start()
{
exit(my_main());
}
int my_main()
{
printf("Hello");
return 0;
}
Compile as:
gcc -nostartfiles hello.c
and you can get an executable out of it.
Use the -c option of your compiler (works for GCC, option probably identical for other c compilers).
From GCC's man page:
When you invoke GCC, it normally does
preprocessing, compilation, assembly
and linking. The "overall options"
allow you to stop this process at an
intermediate stage. For example, the
-c option says not to run the linker. Then the output consists of object
files output by the assembler.
The linking phase is the step that looks for main() and complains if it doesn't find it.
You can compile individual files without main, but you cannot link them and of course cannot run them since they are not complete programs. Note that valgrind is not a static analysis tool but a runtime tool, and therefore it is useless on individual translation units not linked into a runnable program.
If you want to test individual files, a common practice is to include something like the following in each file:
#ifdef UNIT_TEST
int main(int argc, char **argv)
{
/* unit test code goes here */
}
#endif
And compile the file with -DUNIT_TEST.
If you want to compile without linking, the above answers are correct, use the -c switch. If you want a "freestanding" executable, then use the -entry:function switch. The default or "hosted environment" executable has the entry point as -entry:mainCRTStartup which calls main. Note that if you are making a freestanding executable, you cannot use the standard libraries beyond the freestanding libraries <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>.
When is a freestanding executable written? Kernels and Drivers. If you are into hobby os-dev, then you need to write them. If you work for a hardware manufacturer, such as graphics card manufacturer, you will need to write drivers for them.
Some use the embedded unit tests, while others write them as separate files with conditional compilation. Remember that #define and makefile commands have some degree of overlap.
To link with no main() in gcc, pick a function for the "entry" in place of main().
When linking, add this option:
-e entry
--entry=entry