I just started to learn C/C++, but I'm a bit confused. I often see the #include
preprocessor directive, with a header file argument:
#include <stdio.h>
#include <iostream.h>
#include "windows.h"
#include <math.h>
But sometimes the .h
is missing:
#include <iostream>
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h
?
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
When you install the compiler, the standard header and library files are also installed into well-known locations. For example, on a Linux or Unix system, the standard headers are typically installed under /usr/include
or /usr/local/include
and the standard libraries are typically installed under /usr/lib
or /usr/local/lib
.
When you #include
the header file, the compiler will look for it in different places depending on whether you use the angle brackets (#include <stdio.h>
) or quotes (#include "myfile.h"
). For example, if you include a header file in angle brackets, gcc
will search for that header in the following directories:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
If you include a header file with quotes, gcc
will first search the current working directory, then additional directories as specified by command-line options, and finally the standard include paths above.
Most compilers allow you to specify additional include paths as arguments to compile command, such as
gcc -o executable-name -I /additional/include/path source-files
But sometimes the .h is missing:
#include <iostream>
This is the C++ convention1; C++ standard headers do not have the .h
extension, I guess to make it look more object-oriented than it really is (that is, you can pretend you're importing the class directly, rather than including the text of the file that describes the class).
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h?
The implementations of the math functions are typically kept in a separate library (code that's already been compiled and archived into a single binary file); depending on the compiler, the math library may or may not be automatically linked into the executable. For example, gcc
does not automatically link in any math library functions, even if you include the math.h
header file. You have to explicitly include the math library as part of the build command:
gcc -o executable-name command-line-options source-files -lm
With gcc
, the convention is that -lname
links in a library named libname.a
2. The standard math library file is named libm.a
, so -lm
tells gcc
to link in the machine code that's contained within libm.a
.
Like the standard headers, the compiler will search for the standard libraries in well-known locations. You can specify additional search paths for libraries that aren't part of the standard installation, like so:
gcc -o executable-name command-line-options source-files -L /additional/library/path -ladditional-library
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
You can put the files pretty much anywhere you want; you'll specify where they are as part of the build command. So, say you're creating a new library named mylib
. You create a new directory under your home directory:
mkdir ~/mylib
cd ~/mylib
Then you create and edit your source files and headers:
cd ~/mylib
vi mylib.h
vi mylib.c
To build mylib
as a static library, do the following:
cd ~/mylib
gcc -c mylib.c
ar libmylib.a mylib.o
So when you're done, the directory ~/mylib
contains the following:
libmylib.a
mylib.c
mylib.h
mylib.o
To use the functions collected in mylib
in a program, you'd specify the header and library include paths as part of the compile command:
gcc -o executable-name command-line-options source-files -I ~/mylib -L ~/mylib -lmylib
So, if you include "mylib.h"
in another program, this will tell the compiler to search for that header in ~/mylib
, and it will tell the linker that the libmylib.a
library will be found under ~/mylib
.
In a real-world situation you'd handle all of the builds with makefiles instead of building everything by hand. You'd also probably set it up so that as part of the build process, all the headers that anyone else would need to use your library would be copied to a separate include
subdirectory, and the library would be written to a separate lib
subdirectory, so you could distribute your library without exposing your source code. In that case, the build command above would look more like:
gcc -o executable-name command-line-options source-files -I ~/mylib/include -L ~/mylib/lib -lmylib
iostream.h
, vector.h
, etc. I'm not sure exactly when that convention changed, but it's been a while.gcc
convention or a *nix
convention; the two have been joined at the hip for so long it's hard to remember sometimes.Actually, the compiler doesn't know anything about other source files, it only knows about the current translation unit. It's the job of the linker to take all translation units and link them together with the libraries to create the executable program, and it's the linker that will resolve all definitions and that notice missing function definitions.
Traditionally, working with C or C++ is a four step process:
The preprocessor is usually built into the compiler, so preprocessing and compiling is only a single step.
As for the "missing" .h
, none of the C++-only standard library header files have that extension.
Standard Template Library headers, such as < algorithm > include source code for the template functions, which get instantiated at compile time, based on the template type(s) involved in source code calls to template functions.
A library is a collection of object files in a single library file. The linker normally only includes the object files needed to satisfy the references to functions or data to build the program, not the entire library file. The exception to this is a dynamic link library, since all of that library will be loaded (if not already loaded) at program load time.
The compiler has default locations for headers using < > and using " ". The headers using " ", can include relative or absolute paths. The relative path may vary depending on the tool set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With