Jun 20, 2015

[C++] Detail matters - study note

reading note for:
CppNow 2015 - Details Matter Alisdair Meredith BloombergLP



Documentation

- Documentation is a Contract
- What Happens if a Contract is Violated?
  - Undefined behavior?
  - throw an exception?
  - terminate the program?
  - log and return?
  - Ultimately, the library author chooses how to support their
    customers
  - *Personal preference: use assertions with customizable
    handler function
 
---------
Narrow vs. Wide Contract:
Reference : [Defensive Programming]
- A wide contract has no preconditions, and so accepts
  all input

- A narrow contract is one with any preconditions, that the
  user is responsible for validating before making a call
  - Such validation may be working with known inputs
    rather than strictly writing checking code before each call
  - Often, pre-conditions bubble up through layers of contracts


Narrow vs. noexcept:
- Design rule for std library specifications
- *noexcept only on wide contracts
- conditional noexcept only when noexcept is vital, e.g., move or swap
- Implementations have freedom to strengthen specification
- and always have, since 1998 standard
- Preserves implementors ability to respond to out-ofcontract calls

Is Narrow or Wide Better?
- Narrower contracts are often easier to implement
- Wider contracts are often easier to use
- Unless they result in a larger set of failure
  post-conditions to test
- Exercise engineering judgement

----------
Avoid Breaking Changes
- If your next release is not compatible with the previous releases,
  users need to audit their whole code base before they can safely update
- If you must break something, prefer a breakage that is loud and clear,
  so is found easily and early
- API breakage - fails to compile
- ABI breakage - fails to link
- Silent behavior change - end users report bugs, oops!
- behavior change is undefined behavior - all bets are off

----------
C++11 Memory Model
- Making concurrency a well specified concern for
  the language introduced some compatibility concerns
- Some compiler optimizations became illegal
- basic_string banned CoW, enabled short string
- ‘begin’ no longer invalidates iterators
- ‘swap’ can now invalidate iterators

----------
Enriching Exceptions
- Potentially unsafe idiom from C++11 onwards
- catch(Type& exception), update the exception object
- *C++11: Same exception object can unwind in several
  threads in parallel
- *Modifications are potential race conditions
- *Preferred idiom: always catch by const &, use
  nested_exception or similar to throw an enriched
  exception if necessary
  http://en.cppreference.com/w/cpp/error/nested_exception
  http://en.cppreference.com/w/cpp/error/rethrow_if_nested


----------
Racing Exceptions
- If we control whole code path, we know whether we risk joining the
  thread that might throw - low risk (code changes under maintenance)
- If we call user code, then we have no control over which exceptions
  might throw
  - function pointer
  - virtual function call
  - template specialization
  - user function found via ADL
- Can limit damage by writing a contract that disallows exceptions from
other threads - but any bugs from violations will be subtle.


----------
Guidelines:
- Document contracts clearly; they define your library
- Testing will reveal incomplete contracts as well
  as broken implementations
- It is generally easier to fix an implementation
  than a contract on a live system
- Exception classes should have no throw copies
    e.g., std exceptions may be immutable ref-counted strings
- Class templates frequently store data in tuples
- Beware of (unexpected) ADL
- Learn the safe idioms, especially for generic code
  - T var{}; // default a value this way
    T var1(var2); // copy an object this way, (i.e for explicit constructor)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.