There is no direct relationship between headers and object files in C
or C++. Compilation process is two stage:
1. Source files are compiled into object files
2. Object files are linked together into executable of sorts
(Actually it's a three stage process, but i'm going to describe it
using two stages).
Stages are isolated from each other and to some extent autonomous.
Object files are kind of intermediate representation of source code
that is later used to produce machine code. I'm sure someone can
correct me on this, but for the sake of simplicity, i think it's OK to
think of them as of IR.
When *compilation unit* is compiled into an object file, it is also
separated from other units. To compile it separately from other units
all relevant source code has to be pulled into the current unit and
compiled. So `#include <something.h>` doesn't include just
something.h, it includes something.h, then all includes that
something.h includes and so on. This is a process similar to
amalgamation of source code, everything is copied into one place and
then compiled as a single unit. After all units are compiled, they
might be joined together by a linker either into a static library,
dynamic library or executable.
This is actually more sophisticated than that, but it does allow you
to do some cool stuff like you can compile your source code into
objects, then ship object files and then link them elsewhere. In fact,
static libraries are just a bunch of object files packed together, but
headers are still required because you need symbol names to refer to
on source code level, therefore libraries are shipped with headers:
you compile with headers and then link with objects.
Since it's the separate stages, you could, for instance, write your
own headers for 3rd party objects, think open source headers for
closed source DirectX SDK.
This description is very superficial and doesn't cover a lot of what
is really going on. The process is very flexible and allows to do all
kinds of stuff in various combinations. Alas this process is also not
very fast and requires some costly steps like you need to pull all
required source code into a single unit to compile it.
Modern C++ is also using a lot of templates, even if you're not
writing templates, you're going to use templates from the standard
library and to use templates you need to transform (instantiate) each
template into concrete code and then (simply put) compile instantiated
template as regular non-templated source code. Because every
compilation unit is being "amalgamated", this process has to be
repeated for every unit, which also takes some time.
There is such thing as C++ modules, but they are quite new
(standardized like a month ago) and not yet widespread. I think they
should be more similar to Go *packages* when source code files are
logically joined into a single entity and for that entity another
intermediate representation is created which is called BMI (binary
module interface) even though it doesn't have to be binary, so
sometimes it's called CMI (compiler module interface).
This CMI is basically a compiler cache, a package, or in terms of C++,
a module interface, can be compiled once and then reused to compile
object files without recompiling the same source code for every unit.
Regarding how packages compilation actually works in Go - this is an
interesting topic. I'm afraid i won't be able to explain it more or
less correctly and i would be glad to read about it too.
сб, 14 нояб. 2020 г. в 04:17, kev kev <
kevthem...@gmail.com>: