- A definition associates a name with an implementation of that name, which could be either data or code:
- A definition of a variable induces the compiler to reserve some space for that variable, and possibly fill that space with a particular value.
- A definition of a function induces the compiler to generate code for that function.
- A declaration tells the C compiler that a definition of something (with a particular name) exists elsewhere in the program, probably in a different C file.
- The C compiler's job is to convert a C file from text that the human can (usually) understand, into stuff that the computer can understand. This output by the compiler is known as an object file.
- The contents of an object file are essentially two kinds of things:
- code, corresponding to the functions in the C file
- data, corresponding to the global variables in the C file (for an initialized global variable, the initial value of the variable also has to be stored in the object file)
- Object code is the sequence of (suitably encoded) machine instructions. that correspond to the C instructions that the programmer has written--all of those ifs and whiles and even gotos.
- Running the program obviously involves executing the machine code, so the operating system clearly has to transfer the machine code from the executable file on the hard disk into the computer's memory, where the CPU can get at it. This chunk of the program's memory is known as the code segment or text segment.
- Initialized variables have particular values that need to be used to begin with, and these values are stored in the object files and in the executable file. When the program is started, the OS copies these values into the program's memory in the data segment.
- For uninitialized variables, the OS can assume that they all just start with the initial value 0, so there's no need to copy any values. This chunk of memory, that gets initialized to 0, is known as the bss segment.
- Local variables are allocated on a piece of memory known as the stack, which grows and shrinks as different functions are called and complete.
- Dynamically allocated memory is taken from an area known as the heap, and the malloc function keeps track of where all the available space in this are is.
- Because both the heap and the stack can change size as the program runs it's quite common to arrange matters so that the stack grows in one direction with the heap grows in the other.
- The most basic incarnation of a library is a static library.
- Note the granularity of what gets pulled in from the library: if some particular symbol's definition is needed, the whole object that contains that symbol's definition is included.
- For popular libraries like the C standard library (normally libc), having a static library has an obvious disadvantage--every executable program has a copy of the same code. This can take up a lot of unnecessary disk space, if every single executable file has a copy of printf and fopen and suchlike.
- A slightly less obvious disadvantage is that once a program has been statically linked, the code in it is fixed forever.
- As an aside, another useful tools is ldd; on Unix platforms this shows the set of shared libraries that an executable (or a shared library) depends on, together with an indication of where those libraries are likely to be found.
- It's normal good practice in C to have a single declaration for any function or global variable, held in a header file.
- The first change that C++ allows is the ability to overload a function, so there can be different versions of the same named functions, differing in the types that the function accepts (the function's signature).
- A constructor is a piece of code that sets up the contents of an object; as such it is conceptually equivalent to an initializer value for a variable but with the key practical difference that it involves arbitrary pieces of code.
20170817
Beginner's Guide to Linkers by David Drysdale
Labels:
compsci
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment