GNU的C++代码书写规范

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

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:

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  <dr@att.com>

* 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
    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>
   void
   template_function(args)
   { }
     -NOT-
 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
   {
   public:
     // Types:
    };
 -NOT-
 template<class _CharT, class _Traits>
 class basic_ios : public ios_base
   {
   public:
     // Types:
    };
 -NOT-
 template<class _CharT, class _Traits>
   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, 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.

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

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

[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<typename _Formal_argument>
     void
     public_template() const throw();

   template<typename _Iterator>
     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<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) {
 // ...
      }
    }
 
 gribble::gribble()
 : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
 { }

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

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值