Compiled languages like C++ require a compiler and a linker.
C++ source files' extensions: .cpp, .c, .cc, .cxx.
Source files AKA translation units: named as such because the compiler translates them into machine code one file at a time.
A special kind of source files are called Header Files and they're not seen by the compiler instead the C++ preprocessor replaces each #include with the content of the corresponding header file before sending the translation units to the compiler.
After compilation, the resulting machine code is placed in an object file which is relocatable and unlinked.
Obj. files can then be collected into groups called libraries which is an archive containing 0 or more obj. files.
Obj. files and Libs are linked into an .exe by the linker.
The linker's job is (1) to ensure that all external refs to funcs and global data are properly resolved and (2) to calculate the final relative address of all machine code as it will appear in memory when the program runs, BUT know that the final absolute base address of the program is not known until the program actually gets loaded into memory, just before running it.
Dynamic Linked Library (DLL) is a special kind of library which acts like a hybrid between a regular static lib and an exe. It's a lib because it has func that can be called by any number of exes. And it acts like an exe because it can be loaded by the OS independently.
The EXE that uses a DLL has partially linked machine code as the rest gets linked/resolved by the OS by locating and loading appropriate DLLs.
Debugging Information is included with the obj file which is used to step through the code.
Inline function expansion is an example of generalized code transformations "Optimization".
Local Optimization:
Operates on small chunks of code known as basic blocks which is a sequence of assembly instructions that doesn't involve a branch.
algebraic simplification
operator strength reduction (x/2 into x >> 1) (less expensive)
code inlining
constant folding
constant propagation
loop unrolling (to eliminate conditional branching)
dead code elimination
instruction reordering
Global Optimization:
Known as Link Time Optimizations (LTO) and are done by the linker operating around a translation unit boundary.
I can type any valid C/C++ expression into the watch window and it will be evaluated and displayed.
I can call functions within the watch window.
I can use variety of suffixes on expressions to change the way the values are displayed, such as " ,d" to force values to be displayed in decimal notations, " ,x" force hexa and " ,n" to treat values as an array of n elements.
AKA hardware breakpoints because they're implemented via a special feature of the CPU's hardware.
Whenever a predefined memory address is written to, an interrupt is raised.
non-debug-only bugs are sometimes caused by uninitialized vars or any other reason that happens in a non-debug build.
I can cast an address to a specific class type in the watch window if it's known that this instance of the class resides at that specific address.
Statistical profilers: unobtrusive, meaning, code runs at same speed wether or not profiling is enabled and it works by sampling the CPU's program counter register. (Intel's VTune).
Instrumenting profilers: provides the most accurate data at the expense of real-time execution of the target program. (IBM's Rational Quantify).
Memory leak is when memory is allocated but never freed while memory corruption occurs when the program inadvertently writes data to the wrong mem location (overwriting whatever data was there).
The chapter is pretty interesting, much of what's in there is new to me. Despite digging deep into details, it wasn't boring at all. At some point in programming this will make more sense.
I'll definetly use what I learnt in this chapter and always take all these concepts into consideration.
Now, on to the next chapter.