3

Why do we have to tell gcc which library to link against when that information is already in source file in form of #include?

For example, if I have a code which uses threads and has:

#include <pthread.h> 

I still have to compile it with -pthread option in gcc:

gcc -pthread test.c 

If I don't give -pthread option it will give errors finding thread function definitions.

I am using this version:

gcc --version gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 
2
  • 2
    Making this a comment and not an answer because it's going to sound pretty unsatisfying, but IMO the answer is "Because we've always done it that way". There's not and has never been a way for a header file to tell the compiler to tell the linker to load a library. (It'd surely be nice if there was, but "We've never done it that way".) Commented Feb 9, 2016 at 18:47
  • 1
    There's definitely justice in what Steve Summit says ("we've always done it that way"), but there are also issues. For example, there can be multiple implementations for a library — shared vs static, debug vs non-debug, version 1 vs version 2 — not to mention the issues that would occur while trying to develop or maintain a library (did I want the system version or the version I'm building, etc). And the libraries may be installed in different locations on different systems. Granted, most of the time the default would work for most people. Controlling the choice requires careful design. Commented Feb 9, 2016 at 19:06

4 Answers 4

4

This may be one of the most common things that trip up beginners to C.

In C there are two different steps to building a program, compilation and linking. For the purposes of your question, these steps connect your code to two different types of files, headers and libraries.

The #include <pthread.h> directive in your C code is handled by the compiler. The compiler (actually preprocessor) literally pastes in the contents of pthread.h into your code before turning your C file into an object file.

pthread.h is a header file, not a library. It contains a list of the functions that you can expect to find in the library, what arguments they take and what they return. A header can exist without a library and vice-versa. The header is a text file, often found in /usr/include on Unix-derived systems. You can open it just like any C file to read the contents.

The command line gcc -lpthread test.c does both compilation and linking. In the old days, you would first do something like cc test.c, then ld -lpthread test.o. As you can see, -lpthread is actually an option to the linker.

The linker does not know anything about text files like C code or headers. It only works with compiled object files and existing libraries. The -l flag tells it which libraries to look in to find the functions you are using.

Sign up to request clarification or add additional context in comments.

Comments

3

The name of the header has nothing to do with the name of the library. Here it's really just by the accident. Most often there are many headers provided by the library.

Especially in C++ there is usually one header per class and the library usually provides classes implementations from the same namespace. In C the headers are organized that they contain some common subset of functions - math.h contains mathematical operations, stdio.h provides IO functions etc.

2 Comments

So why we don't tell gcc about others, like <stdio> etc. ? How should I know which libraries I should tell about to gcc?
@Arash : stdio.h is part of standard C library (libc, -lc) which is automatically linked to every program.
2

They are two separate things. .h files holds the declarations, sometimes the inline function also. As we all know, every functions should have an implementation/definition to work. These implementations are kept seperately. -lpthread, for example is the library which holds the implementation of the functions declared in headers in binary form.

Separating the implementation is what people want when you don't want to share your commercial code with others

So,

gcc -pthread test.c 

tell gcc to look for definitions declared in pthread.h in the libpthread. -pthread is expanded to libpthread by linker automatically

1 Comment

On Unix/Linux platforms, the -pthread flag is actually telling the linker to link with a library named either libpthread.so or libpthread.a, depending possibly on other flags in the command.
1

there are/were compilers that you told it where the lib directory was and it simply scanned all the files hoping to find a match. then there are compilers that are the other extreme where you have to tell it everything to link in. the key here is include simply tells the compiler to look for some definitions or even simpler to include some external file into this file. this does not necessarily have any connection to a library or object, there are many includes that are not tied to such things and it is a bad assumption. next the linker is a different step and usually a different program from the compiler, so not only does the include not have a one to one relationship with an object or library, the linker is not the compiler.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.