img myan

GNU的C++代码书写规范,C语言之父Dennis Ritchie亲自修订

发表于2002/2/1 16:58:00  6919人阅读

C++ Standard Library Style Guidelines  DRAFT 1999-02-26

This library is written to appropriate C++ coding standards.  As such,
it is intended to precede the recommendations of the GNU Coding
Standard, which can be referenced here:


ChangeLog entries for member functions should use the
classname::member function name syntax as follows:

1999-04-15  Dennis Ritchie  <dr@att.com>

* src/basic_file.cc (__basic_file::open): Fix thinko in

Notable areas of divergence from what may be previous local practice
(particularly for GNU C) include:

01. Pointers and references
  char* p = "flop";
  char& c = *p;
  char *p = "flop";  // wrong
  char &c = *p;      // wrong
    Reason: In C++, definitions are mixed with executable code.  Here,      
    p          is being initialized, not *p.  This is near-universal
            practice among C++ programmers; it is normal for C hackers
            to switch spontaneously as they gain experience.

02. Operator names and parentheses
  operator == (type)  // wrong
    Reason: The == is part of the function name.  Separating
            it makes the declaration look like an expression.

03. Function names and parentheses
  void mangle()
  void mangle ()  // wrong

     Reason: no space before parentheses (except after a control-flow
     keyword) is near-universal practice for C++.  It identifies the
     parentheses as the function-call operator or declarator, as
     opposed to an expression or other overloaded use of parentheses.

04. Template function indentation
  template<typename T>
    { }
  template<class T>
  void template_function(args) {};
     Reason: In class definitions, without indentation whitespace is
             needed both above and below the declaration to distinguish
     it visually from other members.  (Also, re: "typename"
     rather than "class".)  T often could be int, which is
     not a class.  ("class", here, is an anachronism.)

05. Template class indentation
  template<typename _CharT, typename _Traits>
    class basic_ios : public ios_base
      // Types:
  template<class _CharT, class _Traits>
  class basic_ios : public ios_base
      // Types:
  template<class _CharT, class _Traits>
    class basic_ios : public ios_base
      // Types:

06. Enumerators
    space = _ISspace,
    print = _ISprint,
    cntrl = _IScntrl,
  enum { space = _ISspace, print = _ISprint, cntrl = _IScntrl };

07. Member initialization lists
   All one line, separate from class name.

  : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
  { }
  gribble::gribble() : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
  { }

08. Try/Catch blocks
  try {
  catch(...) {
  try { // } catch(...) { // }

09. Member functions declarations and defintions
   Keywords such as extern, static, export, explicit, inline, etc
   go on the line above the function name. Thus

  virtual int  
  virtual int foo()

Reason: GNU coding conventions dictate return types for functions
     are on a separate line than the function name and parameter list
     for definitions. For C++, where we have member functions that can
.    be either inline definitions or declarations, keeping to this
     standard allows all member function names for a given class to be
aligned to the same margin, increasing readibility.

10. Invocation of member functions with "this->"
   For non-uglified names, use this->name to call the function.


The library currently has a mixture of GNU-C and modern C++ coding
styles.  The GNU C usages will be combed out gradually.

Name patterns:

For nonstandard names appearing in Standard headers, we are constrained
to use names that begin with underscores.  This is called "uglification".
The convention is:

  Local and argument names:  __[a-z].*

    Examples:  __count  __ix  __s1 

  Type names and template formal-argument names: _[A-Z][^_].*

    Examples:  _Helper  _CharT  _N

  Member data and function names: _M_.*

    Examples:  _M_num_elements  _M_initialize ()

  Static data members, constants, and enumerations: _S_.*

    Examples: _S_max_elements  _S_default_value

Don't use names in the same scope that differ only in the prefix,
e.g. _S_top and _M_top.  See BADNAMES for a list of forbidden names.
(The most tempting of these seem to be and "_T" and "__sz".)

Names must never have "__" internally; it would confuse name
unmanglers on some targets.  Also, never use "__[0-9]", same reason.


#ifndef  _HEADER_
#define  _HEADER_ 1

namespace std
  class gribble
    // ctor, op=, dtor
    gribble() throw();

    gribble(const gribble&);

    gribble(int __howmany);

    operator=(const gribble&);

    ~gribble() throw ();

    // argument
    inline void 
    public_member(const char* __arg) const;

    // in-class function definitions should be restricted to one-liners.
    one_line() { return 0 }

    two_lines(const char* arg)
      { return strchr(arg, 'a'); }

    inline int
    three_lines();  // inline, but defined below.

    // note indentation
    template<typename _Formal_argument>
      public_template() const throw();

    template<typename _Iterator>

    class _Helper;

    int _M_private_data;
    int _M_more_stuff;
    _Helper* _M_helper;
    int _M_private_function();

    enum _Enum

    static void

// More-or-less-standard language features described by lack, not presence:
# ifndef _G_NO_LONGLONG
  extern long long _G_global_with_a_good_long_name;  // avoid globals!
# endif

  // avoid in-class inline definitions, define separately;
  //   likewise for member class definitions:
  inline int
  gribble::public_member() const
  { int __local = 0; return __local; }

  class gribble::_Helper
    int _M_stuff;

    friend class gribble;

// Names beginning with "__": only for arguments and
//   local variables; never use "__" in a type name, or
//   within any name; never use "__[0-9]".

#endif /* _HEADER_ */

namespace std {

  template<typename T>  // notice: "typename", not "class", no space
    long_return_value_type<with_many, args> 
    function_name(char* pointer,               // "char *pointer" is wrong.
  char* argument,
  const Reference& ref)
      // int a_local;  /* wrong; see below. */
      if (test)
  nested code
      int a_local = 0;  // declare variable at first use.

      //  char a, b, *p;   /* wrong */
      char a = 'a';
      char b = a + 1;
      char* c = "abc";  // each variable goes on its own line, always.

      // except maybe here...
      for (unsigned i = 0, mask = 1; mask; ++i, mask <<= 1) {
  // ...
  : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
  { }

  inline int
    // doesn't fit in one line.


0 0



取 消