GNU的C++程式碼書寫規範,C語言之父Dennis Ritchie親自修訂 (轉)

gugu99發表於2008-05-25
GNU的C++程式碼書寫規範,C語言之父Dennis Ritchie親自修訂 (轉)[@more@]C++ Standard Library Style Gulines  DRAFT 1999-02-26
-------------------------------------

This library is written to appropriate C++ coding standards.  As such,
it is intended to precede the recommendations of the 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 

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

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;
  -NOT-
  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 ers
  to switch spontaneously as they gain experience.

02. Operator names and parentheses
  operator==(type)
  -NOT-
  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()
  -NOT-
  void mangle ()  // wrong

  Reason: no space before parentheses (except after a control-flow
  key) 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
  void
  template_function(args)
  { }
  -NOT-
  template
  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
  class basic_i: public ios_base
  {
  public:
  // Types:
  };
  -NOT-
  template
  class basic_ios : public ios_base
  {
  public:
  // Types:
  };
  -NOT-
  template
  class basic_ios : public ios_base
  {
  public:
  // Types:
  };

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

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

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

08. Try/Catch blocks
  try {
  //
  } 
  catch(...) {
  //
  } 
  -NOT-
  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 
  foo()
  -NOT-
  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, kee 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.

  this->sync()
  -NOT-
  sync()

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 underres.  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.

--------------------------

[BY EXAMPLE]
 
#ifndef  _HEADER_
#define  _HEADER_ 1

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

  gribble(const gribble&);

  explicit
  gribble(int __howmany);

  gribble&
  operator=(const gribble&);

  virtual
  ~gribble() throw ();

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

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

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

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

  // note indentation
  template
  void
  public_template() const throw();

  template
  void
  other_template();

  private:
  class _Helper;

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

  enum _Enum
  {
_S_one,
_S_two
  };

  static void
  _S_initialize_library();
  };

// 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  // notice: "typename", not "class", no space
  long_return_value_type 
  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) {
  // ...
  }
  }
 
  gribble::gribble()
  : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
  { }

  inline int
  gribble::three_lines()
  {
  // doesn't fit in one line.
  }

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1004555/,如需轉載,請註明出處,否則將追究法律責任。

相關文章