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

    技术2022-05-11  170

    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)