C++ Coding Standards Cover
Order on Amazon
Errata
Bibliography
An acclaimed, award-winning bestseller, C++ Coding Standards sets, so to speak, the standard of coding standards by fostering a lucid, powerful approach that focuses on essentials of programming in C++ and at large, and never trying to objectify the subjective (such as brace placement and other formatting details).

Only five months after hitting the shelves, C++ Coding Standards is already extremely popular worldwide, and its recognition is steadily increasing. As of April 3rd 2005, C++ Coding Standards is being translated in ten languages. Translations to Chinese Simplified (China), Chinese Traditional (Taiwan), Czech, and French are already underway. (Also, good news for English language readers in India—a low-cost English language reprint will soon be available.) Translations to Hindi, Hungarian, Japanese, Korean, Polish, and Russian are coming soon.

C++ Coding Standards has had a long genesis. The one thing that makes it extremely hard to write about coding standards is that it's very hard to please everyone. How could one ever find the recipe to those 101 rules that most everybody would agree with? It took Herb and Andrei two years to figure that out. To shed light on the book's approach, below is an unedited fragment from the manuscript's preface. The fragment didn't make it in the final book for space reasons, but it is nice and well-written (or so the authors think!), and gives a good idea on the essence of the book.

Here’s a little story that we hope will shed light on our approach in writing this book. The scene is a pub. At a corner table sit four people, variously dressed in period costume. By their conversation it is apparent that they are writers, and they are discussing the best way to write.

On the left, Edgar Allan Poe argues fervently, if with somewhat morbid imagery, in favor of a romantic, vivid style. To his right, Marcel Proust holds forth in favor of long, baroque sentences, full of rhythm, breadth, and color. Facing them, Hemingway speaks tersely, and would prefer a short, stylistically Spartan style, almost like a newspaper column. None questions that the others are also great writers, or that the others' styles are wrong, but each revels in the creative expression natural to himself.

It is at this point, partway through the discussion, that the fourth person at the table piped up: “You know what I think about style? Forget grammar. All those pesky rules to follow. I can get my point across even when I don't follow grammatical rules too much, so they're not really necessary. People should be able to figure out what I mean. And what's the deal with vocabulary, anyhow? If I need to say ‘big,’ I say ‘big,’ and if I need to say it again, I'll repeat ‘big.’ All those synonyms are snooty. And while I'm at it, I don't care much for punctuation either. I use it only when things would be ambiguous, otherwise why bother.”

The foolish man is not allowed to go on for very long before Poe, Proust, and Hemingway dump beer on his head. Even though the three masters prefer different styles, they would be equally disapproving of the fourth's repudiation of all rules. You have to know what the rules are, after all, before you know when and if to (rarely) break them.

We believe that all good writers obey many good rules in their work, and yet such good rules don’t make them feel constrained. And we believe this principle applies equally to writing software as it does to writing the classic novel.

Our goal in this book is to find those things that form the fabric of good code, no matter the style. We hope that you will not find in this book any rules that would make miserable a teammate of yours who’s a Poe, Proust, or Hemingway of coding. They are intended to be the basic rules of grammar, of vocabulary, and of diction for writing sound software in C++.

A problem with code (as opposed to prose) is that it is ultimately consumed by a machine, and some people use “well, it works” as an implied and irrefutable argument of wellness. It is not.


Table of Contents

Preface

    Organizational and Policy Issues

  1. Don’t sweat the small stuff. (Or: Know what not to standardize.) 2
  2. Compile cleanly at high warning levels. 4
  3. Use an automated build system. 7
  4. Use a version control system. 8
  5. Invest in code reviews. 9

    Design Style

  6. Give one entity one cohesive responsibility. 12
  7. Correctness, simplicity, and clarity come first. 13
  8. Know when and how to code for scalability. 14
  9. Don’t optimize prematurely. 16
  10. Don’t pessimize prematurely. 18
  11. Minimize global and shared data. 19
  12. Hide information. 20
  13. Know when and how to code for concurrency. 21
  14. Ensure resources are owned by objects. Use explicit RAII and smart pointers. 24

    Coding Style

  15. Prefer compile- and link-time errors to run-time errors. 28
  16. Use const proactively. 30
  17. Avoid macros. 32
  18. Avoid magic numbers. 34
  19. Declare variables as locally as possible. 35
  20. Always initialize variables. 36
  21. Avoid long functions. Avoid deep nesting. 38
  22. Avoid initialization dependencies across compilation units. 39
  23. Minimize definitional dependencies. Avoid cyclic dependencies. 40
  24. Make header files self-sufficient. 42
  25. Always write internal #include guards. Never write external #include guards. 43

    Functions and Operators

  26. Take parameters appropriately by value, (smart) pointer, or reference. 46
  27. Preserve natural semantics for overloaded operators. 47
  28. Prefer the canonical forms of arithmetic and assignment operators. 48
  29. Prefer the canonical form of ++ and --. Prefer calling the prefix forms. 50
  30. Consider overloading to avoid implicit type conversions. 51
  31. Avoid overloading &&, ||, or , (comma). 52
  32. Don’t write code that depends on the order of evaluation of function arguments. 54

    Class Design and Inheritance

  33. Be clear what kind of class you’re writing. 56
  34. Prefer minimal classes to monolithic classes. 57
  35. Prefer composition to inheritance. 58
  36. Avoid inheriting from classes that were not designed to be base classes. 60
  37. Prefer providing abstract interfaces. 62
  38. Public inheritance is substitutability. Inherit, not to reuse, but to be reused. 64
  39. Practice safe overriding. 66
  40. Consider making virtual functions nonpublic, and public functions nonvirtual. 68
  41. Avoid providing implicit conversions. 70
  42. Make data members private, except in behaviorless aggregates (C-style structs). 72
  43. Don’t give away your internals. 74
  44. Pimpl judiciously. 76
  45. Prefer writing nonmember nonfriend functions. 79
  46. Always provide new and delete together. 80
  47. If you provide any class-specific new, provide all of the standard forms (plain, in-place, and nothrow). 82

    Construction, Destruction, and Copying

  48. Define and initialize member variables in the same order. 86
  49. Prefer initialization to assignment in constructors. 87
  50. Avoid calling virtual functions in constructors and destructors. 88
  51. Make base class destructors public and virtual, or protected and nonvirtual. 90
  52. Destructors, deallocation, and swap never fail. 92
  53. Copy and destroy consistently. 94
  54. Explicitly enable or disable copying. 95
  55. Avoid slicing. Consider Clone instead of copying in base classes. 96
  56. Prefer the canonical form of assignment. 99
  57. Whenever it makes sense, provide a no-fail swap (and provide it correctly). 100

    Namespaces and Modules

  58. Keep a type and its nonmember function interface in the same namespace. 104
  59. Keep types and functions in separate namespaces unless they’re specifically intended to work together. 106
  60. Don’t write namespace usings in a header file or before an #include. 108
  61. Avoid allocating and deallocating memory in different modules. 111
  62. Don’t define entities with linkage in a header file. 112
  63. Don’t allow exceptions to propagate across module boundaries. 114
  64. Use sufficiently portable types in a module’s interface. 116

    Templates and Genericity

  65. Blend static and dynamic polymorphism judiciously. 120
  66. Customize intentionally and explicitly. 122
  67. Don’t specialize function templates. 126
  68. Don’t write unintentionally nongeneric code. 128

    Error Handling and Exceptions

  69. Assert liberally to document internal assumptions and invariants. 130
  70. Establish a rational error handling policy, and follow it strictly. 132
  71. Distinguish between errors and non-errors. 134
  72. Design and write error-safe code. 137
  73. Prefer to use exceptions to report errors. 140
  74. Throw by value, catch by reference. 144
  75. Report, handle, and translate errors appropriately. 145
  76. Avoid exception specifications. 146

    STL: Containers

  77. Use vector by default. Otherwise, choose an appropriate container. 150
  78. Use vector and string instead of arrays. 152
  79. Use vector (and string::c_str) to exchange data with non-C++ APIs. 153
  80. Store only values and smart pointers in containers. 154
  81. Prefer push_back to other ways of expanding a sequence. 155
  82. Prefer range operations to single-element operations. 156
  83. Use the accepted idioms to really shrink capacity and really erase elements. 157

    STL: Algorithms

  84. Use a checked STL implementation. 160
  85. Prefer algorithm calls to handwritten loops. 162
  86. Use the right STL search algorithm. 165
  87. Use the right STL sort algorithm. 166
  88. Make predicates pure functions. 168
  89. Prefer function objects over functions as algorithm and comparer arguments. 170
  90. Write function objects correctly. 172

    Type Safety

  91. Avoid type switching; prefer polymorphism. 174
  92. Rely on types, not on representations. 176
  93. Avoid using reinterpret_cast. 177
  94. Avoid using static_cast on pointers. 178
  95. Avoid casting away const. 179
  96. Don't use C-style casts. 180
  97. Don’t memcpy or memcmp non-PODs. 182
  98. Don’t use unions to reinterpret representation. 183
  99. Don’t use varargs (ellipsis). 184
  100. Don’t use invalid objects. Don’t use unsafe functions. 185
  101. Don’t treat arrays polymorphically. 186

Bibliography (7 pages)

Summary of Summaries (13 pages)

Index (12 pages)