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:

  1. C++ Core Guidelines List
    • A list of rules/best practices to follow
  2. Guideline Support Library
    • A collection of utilities that make following the guidelines easier, and replace 'bad' code
  3. 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

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

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

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

Made with Slides.com