天天看點

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

GNU的C++代碼書寫規範,C語言之父Dennis Ritchie親自修訂 (轉)[@[email protected]]C++ Standard Library Style Gu idelines  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:

http://www.gnu.ai.mit.edu/prep/standards_toc.html

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 hackers

  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 word) 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 os : 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 ping 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 under SCOres.  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

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; 

  if (test)

  {

  nested code

  }

  int a_local = 0;  // declare variable at first use.

  //  char a, b, *p; 

  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/10752043/viewspace-996612/,如需轉載,請注明出處,否則将追究法律責任。

轉載于:http://blog.itpub.net/10752043/viewspace-996612/

繼續閱讀