Contents
See also:
C++ style guides
Qt's Coding Style and Coding Conventions
isocpp/CppCoreGuidelines: The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++, from Bjarne Stroustrup and Herb Sutter. More easily readable version
`const` correctness
Formatting
ClangFormat: auto-formats C++ code
Git hook running clang-format. Don't use this!
Static analysis tools
Clang-Tidy: C/C++ linting tool, à la Google's cpplint.
clang-tidy -checks='*' *.cpp -- -std=c++11
Clang Static Analyzer: sets CC and CXX to use alternate compiler to do analysis
# Highest severity warnings only (i.e. memory leaks, etc)
cppcheck --enable=all *.cpp
# Everything except style-related linting
cppcheck --enable=warning,performance,portability,information,missingInclude \
--std=c++11 --library=std.cfg --verbose --quiet \
*.cpp
Overview articles:
Thread safety analysis (TSA)
Documentation:
Thread Safety Analysis in C and C++: CMU blog article on TSA
Thread safety analysis support for libc++, annotating mutex, lock_guard, etc
Example projects:
ClangBuiltLinux/thread-safety-analysis: Linux kernel w/ TSA annotations
Chromium, annotation macros, from base/thread_annotations.h. Macros are named different, and they use deprecated TSA names.
Lifetime safety analysis
Lifetime profile v1.0 posted, initial blog post by Herb Sutter, with link to the Lifetime profile v1.0 paper
mgehre/llvm-project: clang implementation
- note: gsl = Guidelines Support Library
Stuff I never remember
Namespacing enums in pre-C++11: https://stackoverflow.com/questions/482745/namespaces-for-enum-types-best-practices#484304
Unnecessary copies w/ `auto`
Beware unncessary copies w/ auto; default semantics is to make a copy.
// Typically there's no reason to copy.
for (const auto &Val : Container) { observe(Val); }
for (auto &Val : Container) { Val.change(); }
// Remove the reference if you really want a new copy.
for (auto Val : Container) { Val.change(); saveSomewhere(Val); }
// Copy pointers, but make it clear that they're pointers.
for (const auto *Ptr : Container) { observe(*Ptr); }
for (auto *Ptr : Container) { Ptr->change(); }
For iterating over maps:
// Nothing changed
for (const auto& [key, value]: some_map) { observ(value); }
for (auto& [key, value]: some_map) { value.change(); }
Don't evaluate `end()` in loops
// BAD
BasicBlock *BB = ...
for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
// ... use I ...
// GOOD (unless you are mutating BB; use the above loop if you are, and document you are doing so)
BasicBlock *BB = ...
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
// ... use I ...
Notes:
https://twitter.com/michael90187356/status/1245830680291848193: no difference? end() will get cached anyway.
Use `const` iterators if not mutating a structure
Expanding on the above:
BasicBlock *BB = ...
for (BasicBlock::const_iterator I = BB->cbegin(), E = BB->cend(); I != E; ++I)
// ... use I ...
Naming
- "create" and "destroy" for heap-allocated (i.e. pointer) objects
- "init" and "finish" for stack-allocated objects
Dynamic loading of DLL/DSOs
Example of loading OpenCL dynamically. Uses a Python parser script to create special header file with defines that map both functions and does appropriate type conversion. https://github.com/opencv/opencv/pull/1542/files
Boost.DLL: Boost library for easily loading DLLs (e.g. for plugins). Cross platform, but requires runtime libraryes boost_system (integrated into C++11?) and boost_filesystem (integrated into C++17).
https://github.com/knusbaum/CPP-Dynamic-Class-Loading: Class for dynamically loading classes (Linux only)