Series 101-2 Development Environment
Tuesday, March 30, 2021
C++ compilers support being passed various flags to control a multitude of options. One such flag determines whether the compiler embeds debugging symbols into/alongside the binary builds, which generates mappings between source code and line numbers that are used by debuggers to set breakpoints, watch variables, modify registers/memory, etc. Most build systems (Make, Ninja, MSBuild, Xcode, etc) group a collection of these options and flags into a build configuration, and most multi-generator build systems (MSBuild, Xcode) provide a handful of built-in defaults (Debug, Release).…more
Series 101-1 Getting Started
Tuesday, March 23, 2021
C++ is a statically typed application/library programming language, where the source code is compiled (and linked) into a native binary for a particular target platform, like x64, ARMv8, etc (and usually also operating system, like Windows, GNU/Linux, Android, etc). The C++ standard only specifies the rules of the language and its behaviour on an abstract machine, and the standard library‘s interface; compilers like Microsoft VC++, LLVM Clang, GCC, Apple C++ (and others) implement the standard and translate the source to actual platform instructions, and also provide the corresponding implementation of the standard library.…more
Debugging
Friday, April 24, 2020
Debugging Symbols When invoking a C++ compiler, several options/flags can be passed, including optimisation level, pre-processor defines, and whether to include debugging symbols in the binary. These symbols are effectively mappings between binary addresses and source code (file, line number, symbol name, etc), which a compatible debugger can use. Including debugging symbols dramatically increases the size of the resulting binary, often by orders of magnitude. A debugger (given an executable with debugging symbols) offers many useful features, such as stepping through code one line at a time, setting breakpoints, watching variables, changing values stored in memory, the entire call stack (when broken), etc.…more
Memory Management
Tuesday, February 25, 2020
C++ Memory Model Unlike higher level languages, the programmer is responsible for all memory management in C/C++. Automatic/stack-allocated memory is automatically cleaned up when it goes out of scope (hence automatic storage duration) and should always be preferred, even for managing heap memory (smart pointers). This is the basis of RAII. A definition like char x = 'a'; will result in the compiler storing enough space (1 byte) to hold one char.…more
Primitive Data Types
Monday, February 24, 2020
Primitive Data Types C/C++ being rather old languages, the width of types like int, long, etc have changed over time, from 16 bit CPUs to 32 bit and now 64 bit ones. This enables programs using such types to be generic and largely usable on all these target CPU architectures (potentially even ones in the future). The only generic type that has a guaranteed size is char (1 signed/unsigned byte on all modern platforms) - this is also a reason why files are read as arrays of chars (bytes).…more