1 2C++ Standard Library Style Guidelines DRAFT 2001-01-15 3------------------------------------- 4 5This library is written to appropriate C++ coding standards. As such, 6it is intended to precede the recommendations of the GNU Coding 7Standard, which can be referenced here: 8 9http://www.gnu.org/prep/standards_toc.html 10 11ChangeLog entries for member functions should use the 12classname::member function name syntax as follows: 13 141999-04-15 Dennis Ritchie <dr@att.com> 15 16 * src/basic_file.cc (__basic_file::open): Fix thinko in 17 _G_HAVE_IO_FILE_OPEN bits. 18 19Notable areas of divergence from what may be previous local practice 20(particularly for GNU C) include: 21 2201. Pointers and references 23 char* p = "flop"; 24 char& c = *p; 25 -NOT- 26 char *p = "flop"; // wrong 27 char &c = *p; // wrong 28 29 Reason: In C++, definitions are mixed with executable code. Here, 30 p is being initialized, not *p. This is near-universal 31 practice among C++ programmers; it is normal for C hackers 32 to switch spontaneously as they gain experience. 33 3402. Operator names and parentheses 35 operator==(type) 36 -NOT- 37 operator == (type) // wrong 38 39 Reason: The == is part of the function name. Separating 40 it makes the declaration look like an expression. 41 4203. Function names and parentheses 43 void mangle() 44 -NOT- 45 void mangle () // wrong 46 47 Reason: no space before parentheses (except after a control-flow 48 keyword) is near-universal practice for C++. It identifies the 49 parentheses as the function-call operator or declarator, as 50 opposed to an expression or other overloaded use of parentheses. 51 5204. Template function indentation 53 template<typename T> 54 void 55 template_function(args) 56 { } 57 -NOT- 58 template<class T> 59 void template_function(args) {}; 60 61 Reason: In class definitions, without indentation whitespace is 62 needed both above and below the declaration to distinguish 63 it visually from other members. (Also, re: "typename" 64 rather than "class".) T often could be int, which is 65 not a class. ("class", here, is an anachronism.) 66 6705. Template class indentation 68 template<typename _CharT, typename _Traits> 69 class basic_ios : public ios_base 70 { 71 public: 72 // Types: 73 }; 74 -NOT- 75 template<class _CharT, class _Traits> 76 class basic_ios : public ios_base 77 { 78 public: 79 // Types: 80 }; 81 -NOT- 82 template<class _CharT, class _Traits> 83 class basic_ios : public ios_base 84 { 85 public: 86 // Types: 87 }; 88 8906. Enumerators 90 enum 91 { 92 space = _ISspace, 93 print = _ISprint, 94 cntrl = _IScntrl 95 }; 96 -NOT- 97 enum { space = _ISspace, print = _ISprint, cntrl = _IScntrl }; 98 9907. Member initialization lists 100 All one line, separate from class name. 101 102 gribble::gribble() 103 : _M_private_data(0), _M_more_stuff(0), _M_helper(0); 104 { } 105 -NOT- 106 gribble::gribble() : _M_private_data(0), _M_more_stuff(0), _M_helper(0); 107 { } 108 10908. Try/Catch blocks 110 try 111 { 112 // 113 } 114 catch (...) 115 { 116 // 117 } 118 -NOT- 119 try { 120 // 121 } catch(...) { 122 // 123 } 124 12509. Member functions declarations and definitions 126 Keywords such as extern, static, export, explicit, inline, etc 127 go on the line above the function name. Thus 128 129 virtual int 130 foo() 131 -NOT- 132 virtual int foo() 133 134 Reason: GNU coding conventions dictate return types for functions 135 are on a separate line than the function name and parameter list 136 for definitions. For C++, where we have member functions that can 137 be either inline definitions or declarations, keeping to this 138 standard allows all member function names for a given class to be 139 aligned to the same margin, increasing readibility. 140 141 14210. Invocation of member functions with "this->" 143 For non-uglified names, use this->name to call the function. 144 145 this->sync() 146 -NOT- 147 sync() 148 149 Reason: Koenig lookup. 150 15111. Namespaces 152 namespace std 153 { 154 blah blah blah; 155 } // namespace std 156 157 -NOT- 158 159 namespace std { 160 blah blah blah; 161 } // namespace std 162 16312. Spacing under protected and private in class declarations: 164 space above, none below 165 ie 166 167 public: 168 int foo; 169 170 -NOT- 171 public: 172 173 int foo; 174 17513. Spacing WRT return statements. 176 no extra spacing before returns, no parenthesis 177 ie 178 179 } 180 return __ret; 181 182 -NOT- 183 } 184 185 return __ret; 186 187 -NOT- 188 189 } 190 return (__ret); 191 192 19314. Location of global variables. 194 All global variables of class type, whether in the "user visable" 195 space (e.g., cin) or the implementation namespace, must be defined 196 as a character array with the appropriate alignment and then later 197 re-initialized to the correct value. 198 199 This is due to startup issues on certain platforms, such as AIX. 200 For more explanation and examples, see src/globals.cc. All such 201 variables should be contained in that file, for simplicity. 202 20315. Exception abstractions 204 Use the exception abstractions found in functexcept.h, which allow 205 C++ programmers to use this library with -fno-exceptions. (Even if 206 that is rarely advisable, it's a necessary evil for backwards 207 compatibility.) 208 20916. Exception error messages 210 All start with the name of the function where the exception is 211 thrown, and then (optional) descriptive text is added. Example: 212 213 __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); 214 215 Reason: The verbose terminate handler prints out exception::what(), 216 as well as the typeinfo for the thrown exception. As this is the 217 default terminate handler, by putting location info into the 218 exception string, a very useful error message is printed out for 219 uncaught exceptions. So useful, in fact, that non-programmers can 220 give useful error messages, and programmers can intelligently 221 speculate what went wrong without even using a debugger. 222 223The library currently has a mixture of GNU-C and modern C++ coding 224styles. The GNU C usages will be combed out gradually. 225 226Name patterns: 227 228For nonstandard names appearing in Standard headers, we are constrained 229to use names that begin with underscores. This is called "uglification". 230The convention is: 231 232 Local and argument names: __[a-z].* 233 234 Examples: __count __ix __s1 235 236 Type names and template formal-argument names: _[A-Z][^_].* 237 238 Examples: _Helper _CharT _N 239 240 Member data and function names: _M_.* 241 242 Examples: _M_num_elements _M_initialize () 243 244 Static data members, constants, and enumerations: _S_.* 245 246 Examples: _S_max_elements _S_default_value 247 248Don't use names in the same scope that differ only in the prefix, 249e.g. _S_top and _M_top. See BADNAMES for a list of forbidden names. 250(The most tempting of these seem to be and "_T" and "__sz".) 251 252Names must never have "__" internally; it would confuse name 253unmanglers on some targets. Also, never use "__[0-9]", same reason. 254 255-------------------------- 256 257[BY EXAMPLE] 258 259#ifndef _HEADER_ 260#define _HEADER_ 1 261 262namespace std 263{ 264 class gribble 265 { 266 public: 267 // ctor, op=, dtor 268 gribble() throw(); 269 270 gribble(const gribble&); 271 272 explicit 273 gribble(int __howmany); 274 275 gribble& 276 operator=(const gribble&); 277 278 virtual 279 ~gribble() throw (); 280 281 // argument 282 inline void 283 public_member(const char* __arg) const; 284 285 // in-class function definitions should be restricted to one-liners. 286 int 287 one_line() { return 0 } 288 289 int 290 two_lines(const char* arg) 291 { return strchr(arg, 'a'); } 292 293 inline int 294 three_lines(); // inline, but defined below. 295 296 // note indentation 297 template<typename _Formal_argument> 298 void 299 public_template() const throw(); 300 301 template<typename _Iterator> 302 void 303 other_template(); 304 305 private: 306 class _Helper; 307 308 int _M_private_data; 309 int _M_more_stuff; 310 _Helper* _M_helper; 311 int _M_private_function(); 312 313 enum _Enum 314 { 315 _S_one, 316 _S_two 317 }; 318 319 static void 320 _S_initialize_library(); 321 }; 322 323// More-or-less-standard language features described by lack, not presence: 324# ifndef _G_NO_LONGLONG 325 extern long long _G_global_with_a_good_long_name; // avoid globals! 326# endif 327 328 // Avoid in-class inline definitions, define separately; 329 // likewise for member class definitions: 330 inline int 331 gribble::public_member() const 332 { int __local = 0; return __local; } 333 334 class gribble::_Helper 335 { 336 int _M_stuff; 337 338 friend class gribble; 339 }; 340} 341 342// Names beginning with "__": only for arguments and 343// local variables; never use "__" in a type name, or 344// within any name; never use "__[0-9]". 345 346#endif /* _HEADER_ */ 347 348 349namespace std 350{ 351 template<typename T> // notice: "typename", not "class", no space 352 long_return_value_type<with_many, args> 353 function_name(char* pointer, // "char *pointer" is wrong. 354 char* argument, 355 const Reference& ref) 356 { 357 // int a_local; /* wrong; see below. */ 358 if (test) 359 { 360 nested code 361 } 362 363 int a_local = 0; // declare variable at first use. 364 365 // char a, b, *p; /* wrong */ 366 char a = 'a'; 367 char b = a + 1; 368 char* c = "abc"; // each variable goes on its own line, always. 369 370 // except maybe here... 371 for (unsigned i = 0, mask = 1; mask; ++i, mask <<= 1) { 372 // ... 373 } 374 } 375 376 gribble::gribble() 377 : _M_private_data(0), _M_more_stuff(0), _M_helper(0); 378 { } 379 380 inline int 381 gribble::three_lines() 382 { 383 // doesn't fit in one line. 384 } 385} // namespace std 386 387