xref: /openbsd-src/gnu/gcc/libstdc++-v3/docs/html/17_intro/C++STYLE (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
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