C++ Core Guidelines Overview
Erich Keane, iCDG Software Engineer
Erich.Keane@intel.com
Presentation Warnings
- Bjarne Stroustrup/Herb Sutter/Neil MacIntosh introduced these concepts over nearly 10 hours, this is a VERY distilled presentation
- In many cases, the presentation will have summarized things significantly, if you've read deeper on the subject already, please share with your coworkers later!
- Questions regarding clarifications are extremely welcomed
- I understand this is controversial, please discuss over coffee/lunch/etc, I'm always open to good discussions!
- Feel free to find me elsewhere and ask questions/make comments/etc!
Why Core Guidelines?
- C was intended to be a 'portable assembly' language designed to be developed with compilers of 1980. Computers are smarter, our languages should be too!
- C++ spent the last 30 years evolving into a fantastically expressive language with no performance hit
- History has shown that certain things 'inherited' from C are the biggest causes of error in C++
- "Within C++, there is a much smaller and cleaner language struggling to get out"--Bjarne Stroustrup
- Make Safe replacements for unsafe code, make dangerous stuff "off by default"
- Create a smaller, simpler, SAFER C++
- Eliminate whole classes of errors! Make the easy way the "right way"
Why Not A New Language?
- If C++ has so many problems, why not a NEW language?
- Adoption of a new language is near-impossible
- C++ is the world's most popular language: We need to leverage its history!
- Compilers/toolchains/etc for C++ are better than for every other language, lets not lose those!
- If we can teach existing developers 'the right way', we can iteratively improve EVERY project, not just new ones!
What IS C++ Core Guidelines?
3 Components:
- C++ Core Guidelines List
- A list of rules/best practices to follow
- Guideline Support Library
- A collection of utilities that make following the guidelines easier, and replace 'bad' code
- Enforcement Tool
- A tool to check for abuse/violations of the Core Guidelines
What IS C++ Core Guidelines?
We all hate coding rules because:
- Usually written with 'prevention' in mind (Don't do...)
- Focus on language feature use, not programming principles
- Usually full of bad advice
- Quickly outdated
- Specialized to a domain
- Not well supported
- Don't provide sufficient guidance
What IS C++ Core Guidelines?
Building a good set requires:
- Comprehensive: Covers all 'general' cases
- Currently a very large set
- Browsable: easy to find the list
- On Github!
- Supported by Tools: Don't memorize, analyze!
- Checkable easily, no huge run-time!
- Multiple tools will be available, similar to Lint!
- Suitable for Gradual Adoption
- Don't Neuter the language!
- Keep C++ full-featured, but safe, flexible and fast!
Core Guidelines List
- A collection of statically enforceable rules to improve code
- Subset the language, use only the good parts!
- Eliminate entire classes of errors: Simplify code, but don't compromise performance!
- Bounds Safety
- Ownership Safety
- Type Safety
- Attack resource leaks, RAII! : delete is a BAD word!
- No dangling Pointers : Explicit ownership!
Core Guidelines List
https://github.com/isocpp/CppCoreGuidelines
- We can't tolerate
- Leaks (failure to free)
- Dangling Pointer usage (use after free)
- Loss of efficiency
- Run-time overhead
- Garbage Collection is both Garbage, AND Collection
- Heavy annotations
- Defeat usability, comprehensibility, adaptability
- Excessive False Positives (90%+ errors should be actual, concrete errors) or built-time
Core Guidelines List
Ambitious:
- Aim to stop:
- Leaks
- Dangling Pointers
- Range Errors
- Use of Uninitialized Data Access
- No misuse of casts/unions/etc
- But Still:
- At Scale
- Zero-overhead principle
Core Guidelines List
How?
- Identify owners, track all pointers
- Add owner<T*> type
- compile-time only to identify ownership
- using owner<T*> = T*;
- explicit use of owner<T*> likely a smell
- Non-owned pointers (bare pointers) shouldn't be deleted!
- Explicitly transfer ownership
- Add owner<T*> type
Core Guidelines List
How?
- Identify owners, track all pointers
- Stop using naked "new"/"delete"
- Use STL/RAII Containers for Ownership
- vector/string/smart pointers, ifstream/etc
- implemented with owner<T*>
- Memory with a defined owner doesn't leak
- Use STL/RAII Containers for Ownership
Core Guidelines List
- Make nulls obvious!
- Create not_null<T*> type: Free except for construction
- bool foo(not_null<int*> myData); no longer needs to check myData, since the type system guarantees not-null!
- Stop using T* to refer to multiple objects, use std::array, array_view or std::vector
- Capture only pointers to the outermost-container
- Create not_null<T*> type: Free except for construction
Guideline Support Library
- Open-source library
- Header Only
- Small collection of types to abstract out 'dangerous' code
- Compile-time safety for commonly used functionality
- Enable RAII
- Markup pointer usages to make them easier to analyze
- Abstract nasty "C-Isms" that often result in errors
- https://github.com/Microsoft/GSL
Guideline Support Library
- using owner<T> = T*
- Used to wrap all 'owned' pointer usage
- Don't delete something you don't own!
- Transfer ownership explicitly
- Used by enforcement tool to ensure proper usage
- at()
- Bounds checked array access!
- Specialization for std::array
- Specialization for static arrays
- template for all others, requires:
- ::value_type
- .size()
- operator [size_t]
Guideline Support Library
- not_null<T*>: Restrict pointer/smart pointer to only hold non-null values
- Zero overhead over type T*!
- Can be completely optimized out!
- Has a few MSVC specific compiler hints to ensure all usages get abstracted out as well!
- allows allows construction from T* or T&, but disallows default and nullptr_t construction!
- implicit conversion to T*, operator->
Guideline Support Library
- array_view<T>
- View into data contained by an array object
- non-owning
- Doesn't copy!
- Implemented as just a T* and a size!
- Meant to replace C array/size pairs:
// Common/Dangerous
void f(int* p, int n) {
p[7] = 9; // Sure this isn't an error?
// How about this one?
for (int i = 0; i<n; ++i) p[i]=7;
}
// Better:
void f(array_view<int> a){
a[7] = 9;// Checkable against size at compile/run time
for (int& x: a)x=7; // Perfectly fine!
}Guideline Support Library
- array_view<T> (continued)
- "Make simple things simple"
- Simpler than old-style
- shorter
- at least as fast (more freedom for optimizers!)
// Common/Dangerous
void f(int* p, int n);
int a[100];
f(a, 100); // OK
f(a, 1000); // Oops, disasterous typo!// Better/safer
void f(array_view<int> a);
int a[100];
// Explicit construction, length deduced
f(array_view<int>{a});
// Even shorter way to write!
f(a);
// Compile-time error!
f({a,1000});Enforcement Tool
- Soon-to-be open source tool
- Currently being developed by Microsoft, included in VS2015 Update 1 (most likely)
- Fast analysis, very-minor addition to compile-time! (Make like Lint!)
- Enforce type-safety more strictly
- Highlight 'dangerous' code
- Identify dangling pointers, make out-of-bounds mistakes more difficult
- The Core Guidelines are TOO long to memorize, make the tool do it for you!
Q & A
Erich.Keane@intel.com
C++ Core Guidelines Overview
By Erich Keane
C++ Core Guidelines Overview
- 1,016