Appendix   One

Style

Code is always written in a particular style. Naming conventions, file name extensions and lexical style are all part of this structure of code we call Style. Discussing style is highly controversial, which is the reason we have placed it in an appendix, to keep it distinct from all other rules and recommendations.

General Aspects of Style

The most important aspect of style, whatever style you use, is to be consistent.

RULES
AND
RECOMMENDATIONS

Style 1.1 Do not mix coding styles within a group of closely related classes.

Style 1.1 Do not mix coding styles within a group of closely related classes.

For each project, or group of closely related classes, you should select a coding style. Code written by one programmer might be maintained by another, so the same style should be used by all programmers within the project. If you modify files from another project, you should stick to the style chosen for that project.

However, sometimes you may be forced to mix code written with different styles. It could, for example, be code reused from previous projects using a different style than the one chosen for your project, or from third party libraries, or from the standard library. In such cases are it can be an option to select the style used by the standard library, or the style used by the third party library, or perhaps a mix between the two styles, or the style described in this appendix. It can be an end in itself to use different styles for different kinds of code, as well as there is obvious reasons for having the same style for all code in the whole project. Mixing libraries is very common, which means that style issues are bound to be a problem, but mixing styles within a group of closely related classes is likely to be very confusing, and should therefore be avoided if possible.

It should be noted that the standard library uses a style that in some cases is different from what we recommend. This is particularly true for how names for classes are written. It is our belief that the amount of confusion should be small since the names and usage of the components in the standard library will be known and used by all programmers and thus easily distinguished from code written by users in a project.

Naming conventions

Parallel to the issue of selecting good names for the abstractions in a program lies the question as to how these names should be written. Should you use uppercase or lowercase characters? How should names consisting of many words be written? In this section we present one such naming style.

RULES
AND
RECOMMENDATIONS

Style 1.2 In names that consist of more than one word, the words are written together and each word that follows the first begins with an uppercase letter.

Style 1.3 The names of classes, typedefs, and enumerated types should begin with an uppercase letter.

Style 1.4 The names of variables and functions should begin with a lower-case letter.

Style 1.5 Let data members have a "M" as suffix.

Style 1.6 The names of macros should be in uppercase.

Style 1.7 The name of an include guard should be the name of the header file with all illegal characters replaced by underscores and all letters converted to uppercase.

Style 1.8 Do not use characters that can be mistaken for digits, and vice versa.

Style 1.2 In names that consist of more than one word, the words are written together and each word that follows the first begins with an uppercase letter.

There are a few different ways to separate words in identifiers. One is to use underscores and another is to let the first letter in each new word be in uppercase. We have chosen the latter approach because such identifiers are shorter and, in our personal opinion, easier to read. Both naming conventions have their pros and cons.

How to separate words in an identifier

 
int max_timeout_time = 1000;      // Not recommended
int maxTimeOutTime = 1000;        // Recommended

Style 1.3 The names of classes, typedefs, and enumerated types should begin with an uppercase letter.

Style 1.4 The names of variables and functions should begin with a lower-case letter.

Type names, like classes and enums, should always begin with an uppercase letter to distinguish them from variables and functions, which we recommend should begin with a lowercase letter.

Naming style

 
class Browser;                      // Class
enum State { green, yellow, red };  // Enum
int n = 0;                          // Local variables
void Browser::show()                // Member function
{
   // ...
};

Style 1.5 Let data members have a "M" as suffix.

It is useful to have a naming convention that clearly distinguishes data members from local variables, function parameters and member functions. We suggest adding an "M" (as in "Member") as suffix to data members. The implementation of member functions is easier to understand if data members are easy to distinguish in the code.

Data member suffix

 
template<class T>
class EmcStack
{
   public:
      // ...
   private:
      unsigned allocatedM;
      T*       vectorM;
      int      topM;
};

Style 1.6 The names of macros should be in uppercase.

Names in all uppercase letters are reserved for macros. This has been the traditional naming convention for macros, and we think it is a good idea to keep this tradition. Macros should, however, be quite unusual in C++, since const variables, enum values and inline functions often are better and safer alternative for macros.

Names of macros

 
#define SQUARE(x) (x)*(x)      /* Recommended */

Style 1.7 The name of an include guard should be the name of the header file with all illegal characters replaced by underscores and all letters converted to uppercase.

Include guards are macros, and as such they should also be in all uppercase letters. We suggest that the name of an include guard should be the name of the header file with all illegal characters replaced by underscores and all letters converted to uppercase.

It is quite important to have a consistent style for the names of these macros, since that will relieve programmers from having to look in the header file to know the name of the include guard. Th e file name should be enough to deduce the name of the include guard.

Names of include guards

 
// In file File.hh
#ifndef FILE_HH
#define FILE_HH

// The rest of the file

#endif /* FILE_HH */

Style 1.8 Do not use characters that can be mistaken for digits, and vice versa.

Some digits are rather similar to some characters. The digit 0 is quite similar to the character O , 1 is similar to l , as well as 5 and S . There is therefore a risk that they are mistaken for each other, which can be confusing.

Integral suffixes

A suffix can be used to specify the type of an integer value. You can use either " L " or " l " if the value is a long int , but the lowercase " l " should be avoided since it can be mistaken for the digit 1 .

 
long i1 = 1l;  // Not recommended
long i2 = 1L;  // Better 

File-name extensions

A convention for choosing file-name extensions will make it easy for tools and humans to distinguish between different types of files.

RULES
AND
RECOMMENDATIONS

Style 1.9 Header files should have the extension " .hh ".

Style 1.10 Inline definition files should have the extension " .icc ".

Rec 2.4 , what to put in inline definition file.

Style 1.9 Header files should have the extension ".hh".

Style 1.10 Inline definition files should have the extension ".icc".

There are many different file name extensions in use. This is a list of some of them:

Header files:

 
.h, .hh, .H, .hpp, .hxx 

Implementation files:

 
.c, .cc, .C, .cpp, .cxx, .cp

Inline definition files:

 
.icc, .i

We have chosen to avoid the extensions .h and .c since they are used by the C standard. We have also avoided all extensions with uppercase letters, like .H and .C , since some operating systems does not distinguish file names with mixed case. Of the ones left to choose from, we selected .hh , .cc and .icc as our recommendation for header files, implementation files and inline definition files.

Using only one standard for the extension for implementation files helps, but for practical reasons, it is often necessary to have different extensions for different platforms. Some compilers do not recognize files with certain extensions, and do further more not allow you to override which suffixes they recognize, which will force a project to use some other extension instead. Fortunately, this should not be particularly important since client code should normally not depend on the name extensions for implementation files.

Lexical style

A lexical style is a preferred way to combine the lexical tokens of the language. Such a style should be chosen to avoid having code that is difficult to read and understand just because different parts of it looks different.

RULES
AND
RECOMMENDATIONS

Style 1.11 The names of parameters to functions should be specified in the function declaration if the type name is insufficient to describe the parameter.

Style 1.12 Always provide an access specifier for base classes and data members.

Style 1.13 The public, protected, and private sections of a class should be declared in that order.

Style 1.14 The keyword struct should only be used for a C-style struct.

Style 1.15 Define inline member functions outside the class definition.

Style 1.16 Write unary operators together with their operand.

Style 1.17 Write access operators together with their operands.

Style 1.18 Do not access static members with ' . ' or ' -> '.

Style 1.11 The names of parameters to functions should be specified in the function declaration if the type name is insufficient to describe the parameter.

The declaration of a function often contains more information than the compiler needs to see. For example, names on formal parameters are only needed in the function definition, not in declarations.

Parameter names are meant to make it easier for a programmer to understand the purpose and usage of a function. It is in general better to supply too many names than too few, but if the type name is sufficient to describe the purpose of a parameter, the declaration will be shorter and as easy to understand as without the name.

Specifying parameter names

 
template<class T>
class list
{
   public:
      list();
      explicit list(const T&);
      list(const list<T>&);
      list<T>& operator=(const list<T>&);
      ~list();
      // member template
      template <class InputIterator> 
      void insert(iterator position,
                  InputIterator first,
                  InputIterator last);
      void insertFirst(const T&);
      void insertLast(const T&);
      // ...
};

The purpose of all member functions above is obvious, just by looking at their names and the type of the parameters, except for the only member function with two parameters of the same type, the insert() member function. To explain the purpose of each parameter, all its parameters has been given names.

Style 1.12 Always provide an access specifier for base classes and data members.

All members of a class are private unless the class has an access specification. Likewise a base class will be private unless declared otherwise. You should not use this default behavior. It is much better to explicitly show the reader of the code what you mean.

I mplicitly given access specifiers

 
// Base class B implicitly declared private

class A : B          // Not recommended
{
      // Not recommended:  
implicit access specifier
      int i;
   public:
      // ...
};

Explicitly given access specifiers

 
// Base class B explicitly declared private

class A : private B  // Recommended
{
   public:
      // ...

   // Recommended: explicit access specifier
   private:
      int i;
};

Style 1.13 The public, protected, and private sections of a class should be declared in that order.

The public part should be most interesting to the user of the class, and should therefore come first. The protected part is of interest to derived classes and should therefore come after the public part, while the private part should be of nobody's interest and should therefore be listed last in the class declaration.

Style 1.14 The keyword struct should only be used for a C-style struct.

There is only one major difference between a struct and a class in C++. Everything in a struct is by default public, which is different from a class where everything by default is private. This is for compatibility with C, since everything in a C struct is public. Apart from that there are no big differences. A struct can have member functions and inherit from other classes. It would be possible to only use struct instead of class, but that would make your code more difficult to understand.

To avoid confusion, the keyword struct should only be used when you are grouping built-in data types into a C-style struct; a POD-struct (POD is an acronym for "plain old data"). A struct should therefore have no member functions, nor data members of class types. In other words, if you group anything in a struct that does not exist in C ( references, c lass objects etc.) then you should use a class instead.

Style 1.15 Define inline member functions outside the class definition.

Inline member functions can be defined inside or outside the class definition. We strongly recommend the second alternative. The class definition will be more compact and comprehensible if no implementation can be seen in the class interface.

Where to implement inline member functions

 
class X
{
   public:
      // Not recommended: function definition in class
      bool insideClass() const { return false; }
      bool outsideClass() const;
};

// Recommended: function definition outside class
inline bool X::outsideClass() const
{
   return true;
}

Style 1.16 Write unary operators together with their operand.

The various operators should be presented to the reader so that their use is completely clear. Some of them look identical but are very different, like unary and binary * . Unary operators such as unary * and ++ are best written together with their operand.

How to write unary operators

 
int* i = new int(77);

cout << * i << endl;    // Not recommended
cout << *i << endl;     // Recommended

Style 1.17 Write access operators together with their operands.

Access operators, such as . and -> are best written together with both their operands.

How to write access operators

 
a->foo();       // Recommended
b.bar();        // Recommended

Style 1.18 Do not access static members with '.' or '->'.

Static members are members of the class and not of an object of the class. Accessing such members as if they were object members would therefore be confusing.

How to access static members

 
class G
{
   public:
      // ...
      static G* create();
      // ...
};

G* G::create()
{
   return new G;
}

G g;
G* gp = new G;
G* gp1 = g.create();     // Not recommended
G* gp2 = gp->create();   // Not recommended
G* gp3 = G::create();    // Recommended