From 4b9c0c038971af8a7415c1ccaf435c5a78f9c73f Mon Sep 17 00:00:00 2001 From: Victor Costan Date: Tue, 20 Feb 2018 14:58:48 -0800 Subject: [PATCH] Minor updates to C++ style guide. --- cppguide.html | 99 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/cppguide.html b/cppguide.html index 7f837ac..b529854 100644 --- a/cppguide.html +++ b/cppguide.html @@ -640,7 +640,14 @@ using ::foo::bar; +
  • To place generated protocol + message code in a namespace, use the + package specifier in the + .proto file. See + + Protocol Buffer Packages + for details.
  • Do not declare anything in namespace std, including forward declarations of @@ -955,7 +962,11 @@ Foo a[] = { Foo(1), Foo(2), Foo(3) }; // fine

    Constant initialization is always allowed. Constant initialization of static storage duration variables should be marked with constexpr -where possible. Any non-local static storage +or where possible the + + +ABSL_CONST_INIT +attribute. Any non-local static storage duration variable that is not so marked should be presumed to have dynamic initialization, and reviewed very carefully.

    @@ -1021,7 +1032,12 @@ does not make an observable difference. For example:

    thread_local variables that aren't declared inside a function -must be initialized with a true compile-time constant. Prefer +must be initialized with a true compile-time constant, +and this must be enforced by using the + + +ABSL_CONST_INIT +attribute. Prefer thread_local over other ways of defining thread-local data.

    @@ -1093,9 +1109,16 @@ variables.

    thread_local variables at class or namespace scope must be initialized with a true compile-time constant (i.e. they must have no - dynamic initialization).

    + dynamic initialization). To enforce this, + thread_local variables at class or namespace scope must be + annotated with + + + ABSL_CONST_INIT + (or constexpr, but that should be rare):

    - +
    ABSL_CONST_INIT thread_local Foo foo = ...;
    +

    thread_local should be preferred over other mechanisms for defining thread-local data.

    @@ -1166,7 +1189,12 @@ for your code , terminating the program may be an appropriate error handling response. Otherwise, consider a factory function -or Init() method. Avoid Init() methods on objects with +or Init() method as described in + + +TotW #42 +. +Avoid Init() methods on objects with no other states that affect which public methods may be called (semi-constructed objects of this form are particularly hard to work with correctly).

    @@ -1226,7 +1254,10 @@ language treats it as one as far as explicit is concerned. expressive by eliminating the need to explicitly name a type when it's obvious.
  • Implicit conversions can be a simpler alternative to - overloading.
  • + overloading, such as when a single + function with a string_view parameter takes the + place of separate overloads for string and + const char*.
  • List initialization syntax is a concise and expressive way of initializing objects.
  • @@ -2924,7 +2955,15 @@ This is typically the case when the I/O is ad-hoc, local, human-readable, and targeted at other developers rather than end-users. Be consistent with the code around you, and with the codebase as a whole; if there's an established tool for -your problem, use that tool instead.

    +your problem, use that tool instead. +In particular, +logging libraries are usually a better +choice than std::cerr or std::clog +for diagnostic output, and the libraries in + +absl/strings +or the equivalent are usually a +better choice than std::stringstream.

    Avoid using streams for I/O that faces external users or handles untrusted data. Instead, find and use the appropriate @@ -2934,7 +2973,10 @@ localization, and security hardening.

    If you do use streams, avoid the stateful parts of the streams API (other than error state), such as imbue(), xalloc(), and register_callback(). -Use explicit formatting functions rather than +Use explicit formatting functions (see e.g. + +absl/strings) +rather than stream manipulators or formatting flags to control formatting details such as number base, precision, or padding.

    @@ -3271,8 +3313,14 @@ problems of printing, comparisons, and structure alignment.

    for your particular case, try to avoid or even upgrade APIs that rely on the printf family. Instead use a library supporting typesafe numeric formatting, such as + + StrCat + or + + Substitute + for fast simple conversions, - std::ostream.

    + or std::ostream.

    Unfortunately, the PRI macros are the only portable way to specify a conversion for the standard bitwidth typedefs (e.g. @@ -3531,7 +3579,8 @@ instance).

  • (Allowed) When the type is clear from local context (in the same expression or within a few lines). Initialization of a pointer or smart pointer with calls -to new +to new and +std::make_unique commonly falls into this category, as does use of auto in a range-based loop over a container whose type is spelled out nearby.
  • @@ -5760,9 +5809,37 @@ case should never execute, treat this as an error. For example: +

    Fall-through from one case label to +another must be annotated using the +ABSL_FALLTHROUGH_INTENDED; macro (defined in +absl/base/macros.h). +ABSL_FALLTHROUGH_INTENDED; should be placed at a +point of execution where a fall-through to the next case +label occurs. A common exception is consecutive case +labels without intervening code, in which case no +annotation is needed.

    - +
    +
    switch (x) {
    +  case 41:  // No annotation needed here.
    +  case 43:
    +    if (dont_be_picky) {
    +      // Use this instead of or along with annotations in comments.
    +      ABSL_FALLTHROUGH_INTENDED;
    +    } else {
    +      CloseButNoCigar();
    +      break;
    +    }
    +  case 42:
    +    DoSomethingSpecial();
    +    ABSL_FALLTHROUGH_INTENDED;
    +  default:
    +    DoSomethingGeneric();
    +    break;
    +}
    +
    +

    Braces are optional for single-statement loops.