Awesome C++
C++ is efficient, expressive, high-level, multi-paradigm, cross-platform programming language.
Programmers who want to productively use C++, should:
- know the language :-)
- know the tools
- IDE, editorconfig, clangd, clang-format, clang-tidy, …
- compilers: g++, clang++, …
- build system: cmake, meson, GNU make, …
- debugging: gdb, valgrind, g++/clang++ sanitizers, clang-analyzer, …
- code management: git, …
- follow best practices and learn new things (e.g. modern standards: C++11/14/17/20/23/…)
- use design patterns and existing libraries
See Awesome Modern C++, Awesome C++, A list of open source C++ libraries
Debugging
Typical debugging workflow:
- use
git bisect
- add custom output commands to the code:
std::cout << "my_variable = " << my_variable << std::endl
- use valgrind
- use a sanitizer
- g++/clang++ compiler options:
-g -fsanitize=...
- address + leak sanitizer:
-fsanitize=address
- memory sanitizer:
-fsanitize=memory
- undefined behavior:
-fsanitize=undefined
- g++/clang++ compiler options:
-
enable detection of floating-point exceptions (NAN, INF, etc.) using the feenableexcept function (which is not available on Windows)
#include <cfenv> #include <csignal> #include <iostream> #ifdef _WIN32 #include <cfloat> static void feenableexcept( uint16_t fpflags ) { unsigned int new_word = 0; if (fpflags & FE_INVALID) new_word |= _EM_INVALID; if (fpflags & FE_DIVBYZERO) new_word |= _EM_ZERODIVIDE; if (fpflags & FE_OVERFLOW) new_word |= _EM_OVERFLOW; unsigned int cw = 0; _controlfp_s(&cw, ~new_word, _MCW_EM); } #endif static void printInfoAndAbort( int sig = 0 ) { if( sig == SIGSEGV ) fprintf( stderr, "Invalid memory reference, aborting...\n" ); else if( sig == SIGFPE ) fprintf( stderr, "Floating-point exception occurred, aborting...\n" ); else fprintf( stderr, "Aborting due to signal %d...\n", sig ); abort(); } int main() { signal( SIGSEGV, printInfoAndAbort ); signal( SIGFPE, printInfoAndAbort ); feenableexcept( FE_ALL_EXCEPT & ~FE_INEXACT ); double a = 1; double b = 0; std::cout << "a/b = " << a/b << std::endl; return 0; }
-
set some compiler macros (e.g.
_GLIBCXX_ASSERTIONS
) - use a debugger like
gdb