Testing, Debugging, and Build Tools¶
A C++ toolchain must manage compilation options, dependencies, linking, tests, and platform differences. Make requirements target-specific and reproducible.
CMake target¶
cmake_minimum_required(VERSION 3.25)
project(cpp_notes LANGUAGES CXX)
add_executable(cpp_notes main.cpp)
target_compile_features(cpp_notes PRIVATE cxx_std_20)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_compile_options(cpp_notes PRIVATE -Wall -Wextra -Wpedantic -Werror)
elseif(MSVC)
target_compile_options(cpp_notes PRIVATE /W4 /WX)
endif()
Prefer target properties over global flags so requirements propagate only where
intended. A CMakeLists.txt is a build description, not a guarantee that every
compiler supports identical diagnostics or options.
Test levels¶
- unit tests exercise a small contract;
- property tests generate inputs and verify invariants;
- integration tests exercise real boundaries and ABI/linkage;
- sanitizer builds detect selected runtime defect classes;
- system tests execute the complete artifact in its environment.
For sorting, verify order, permutation preservation, empty/singleton cases, duplicates, extremes, and agreement with a trusted implementation. The language-independent testing-techniques guide develops property-based testing, contracts, doubles, and nondeterminism further.
Compiler diagnostics¶
Enable a strong warning set and understand each suppression. Different compilers find different problems; testing with more than one compiler increases coverage. Warnings are not a substitute for tests or language correctness.
Sanitizers¶
Where supported, AddressSanitizer detects many spatial and temporal memory errors, UndefinedBehaviorSanitizer detects selected undefined operations, and ThreadSanitizer detects many data races. They add overhead, do not cover every defect, and are most useful in dedicated test configurations.
Compiler and platform support varies; check the selected toolchain documentation.
Static analysis and formatting¶
Static analyzers inspect paths without executing them and can enforce selected Core Guidelines or project rules. Formatters remove style debate but do not improve architecture. Treat generated fixes as reviewable changes.
Debugging and profiling¶
Build with debug information and use a debugger to inspect control flow and state. Use sampling or instrumentation profilers for performance. Guessing from source can miss inlining, allocation, cache misses, contention, and system calls. Use the shared debugging and profiling workflow to connect evidence to a falsifiable hypothesis.
Continuous integration¶
Compile cleanly, run tests, and exercise sanitizer/static-analysis configurations where practical. Record compiler versions and language mode. Never publish a performance comparison from debug and optimized builds as though they were equivalent.