[Halld-offline] [Fwd: CLEO coding standard]

David Lawrence davidl at jlab.org
Thu Sep 17 11:43:01 EDT 2009


Hi Mark et al.,

    In case anyone is interested, the minutes of the very brief 
discussion we had on this at the software meeting 3 years ago can be 
found here:

http://www.jlab.org/Hall-D/software/wiki/index.php/August_14%2C_2006_Software

It might help to prime us for the discussion of this at the next offline 
meeting.

Regards,
-David

Mark M. Ito wrote:
> Folks,
>
> Matt Shepherd sent this to me last week. I think it serves as an 
> example of what we might want to adopt for a coding standard and can 
> serve as a starting point for a discussion. Read it over and send out 
> your comments to the list or to me if so moved. We will discuss the 
> idea of standards at a future Offline meeting, of course.
>
>  -- Mark
>
>
> ------------------------------------------------------------------------
>
> Subject:
> CLEO coding standard
> From:
> Matthew Shepherd <mashephe at indiana.edu>
> Date:
> Sat, 12 Sep 2009 09:03:39 -0400
> To:
> "Mark M. Ito" <marki at jlab.org>
>
> To:
> "Mark M. Ito" <marki at jlab.org>
>
>
>
>
> ------------------------------------------------------------------------
>
>
>   DRAFT
>
> Copyright 1996, Cornell University.
>
> Portions of this document are derived from /Programming in C++: Rules 
> and Recommendations/ Copyright 1990-1992 by Ellemtel Telecommunication 
> Systems Laboratories.
>
> Permission is granted to any individual or institution to use, copy, 
> modify, and distribute this document, provided that this complete 
> copyright and permission notice is maintained intact in all copies.
>
> Ellemtel Telecommunication Systems Laboratories makes no 
> representations about the suitability of this document or the examples 
> described herein for any purpose. It is provided "as is" without any 
> expressed or implied warranty.
>
> Cornell University and the CLEO collaboration make no representations 
> about the suitability of this document or the examples described 
> herein for any purpose. It is provided "as is" without any expressed 
> or implied warranty.
>
> $Id: c++std.html,v 1.10 1996/04/23 19:49:02 dsr Exp $
>
>
>   Contents
>
>    1. Introduction <#intro>
>    2. Rules <#rules>
>    3. Recommendations <#recommend>
>    4. Portability Recommendations <#portability>
>    5. Style Recommendations <#style>
>
>
>   Introduction
>
> The base document for the CLEO III C++ coding standard is assumed to 
> be the ISO/ANSI C++ standard. Since that standard does not exist yet, 
> this draft is based on the April 1995 X3J16 working paper. Not all 
> features referenced are currently available in all (or, in some cases, 
> any) C++ compiler; a future version of this document may indicate 
> appropriate workarounds (where possible).
>
>
>   Rules
>
>   1.
>
>       Every time a rule is broken must be clearly documented. No
>       exceptions.
>
>       "This module violates rule 1" is not allowed.
>
>   2.
>
>       Every file that contains source code must begin with a CLEO
>       standard header with all fields filled in.
>
>       Suitable source file skeletons can be found in
>       /cleo/util/skeletons. A completed header should look something
>       like this (not quite identical to what is in
>       /cleo/util/templates--fix):
>
>       // -*- C++ -*-
>       //
>       // Package:     Tracker
>       // Module:	Helix
>       //
>       // Description: Encapsulates a 5-parameter helix.
>       //
>       // Usage:
>       //      [class and public member function
>       //       documentation goes here]
>       //
>       // Author:      A. Trackfinder
>       // Created:     Thu Jan  1 00:00:01 EST 1996
>       // $Id$
>       //
>       // Revision history
>       //
>       // $Log$
>             
>   3.
>
>       Every include file must be protected against multiple inclusion
>       with a |#define| of the form <package>_<module>|_H|, e.g.
>
>       #if !defined(TRACKER_HELIX_H)
>       #define TRACKER_HELIX_H
>       // ...
>       #endif
>             
>   4.
>
>       All comments and names are to be written in English.
>
>   5.
>
>       Never use "|..|" in |#include| directives.
>
>   6.
>
>       The identifier of every globally visible class, enumeration
>       type, type definition, function, constant, and variable in a
>       class library should be encapsulated in the unique namespace for
>       that library.
>
>   7.
>
>       Do not use names that differ only by the use of uppercase and
>       lowercase letters.
>
>   8.
>
>       Do not use identifiers which begin with two underscores (`__')
>       or one underscore (`_') followed by a capital letter. Do not use
>       identifiers with global or file scope which begin with one
>       underscore (`_').
>
>       These are all reserved to the compiler by the ANSI standard.
>
>   9.
>
>       All classes should be declared following the CLEO standard class
>       skeleton.
>
>       Public, protected, and private are to declared explicitly in
>       that order; do not use default access control. By placing the
>       public section first, everything that is of interest to a user
>       is gathered in the beginning of the class definition. The
>       protected section may be of interest to designers when deriving
>       from the class. The private section contains details that should
>       have the least general interest.
>
>       class Helix {
>          // friend classes and functions
>          public:
>          // constants, enums and typedefs
>          // Constructors and destructor
>             Helix();
>             virtual ~Helix();
>
>          // member functions
>          // const member functions
>          // static member functions
>          protected:
>          // protected member functions
>          // protected const member functions
>          private:
>          // Constructors and destructor
>             Helix(const Helix&);
>          // assignment operator(s)
>             const Helix& operator=( const Helix& );
>          // private member functions
>          // private const member functions
>          // data members
>          // static data members
>       };
>             
>
>       Suitable skeletons can be found in /cleo/util/skeletons.
>
>  10.
>
>       No non-empty member functions are to be defined within the class
>       definition.
>
>       Class definitions are less compact and more difficult to read
>       when they include definitions of member functions. It is also
>       easier to change an inline member function to an ordinary member
>       function if the definition of the inline function is placed
>       outside of the class definition.
>
>       The only exception is for "trivial" functions which are
>       guaranteed to not change, such as accessor functions to data
>       whose representation is fixed, or forwarding functions.
>
>  11.
>
>       All class member data should be private.
>
>       A public variable represents a violation of one of the basic
>       principles of object-oriented programming, namely, encapsulation
>       of data. For example, if there is a class of the type
>       BankAccount, in which account_balance is a public variable, the
>       value of this variable may be changed by any user of the class.
>       However, if the variable has been declared private, its value
>       may be changed only by the member functions of the class.
>
>       If public data is avoided, its internal representation may be
>       changed without users of the class having to modify their code.
>       A principle of class design is to maintain the stability of the
>       public interface of the class. The implementation of a class
>       should not be a concern for its users.
>
>       The use of protected variables in a class is not recommended,
>       since these variables become visible to any derived classes. The
>       names or types of variables in a base class may then not be
>       changed since the derived classes may depend on them. If a
>       derived class must access data in its base class, make a special
>       |protected| interface in the base class containing functions
>       which return private data. This solution would not imply any
>       degradation of performance if the functions are defined inline.
>
>  12.
>
>       A member function that does not affect the state of an object is
>       to be declared |const|.
>
>       Member functions declared as |const| may not modify non-mutable
>       member data and are the only functions which may be invoked on a
>       |const| object. A |const| declaration is an excellent insurance
>       that objects will not be modified when they should not be.
>
>  13.
>
>       |const| member functions may not alter any data that changes the
>       behavior of the object.
>
>       It is possible for an object to have member data that can be
>       changed without changing the significant behavior of the object,
>       such as use counters used for profiling, or caches. Such member
>       data should be declared with the |mutable| keyword.
>
>  14.
>
>       Constructors and destructors must not be inline.
>
>       Since a constructor or destructor always invoke the constructors
>       or destructors of its base classes, inlining these functions can
>       cause hidden code bloat.
>
>  15.
>
>       All classes should declare a *copy constructor*, an *assignment
>       operator* from its own type, a default *constructor* and a
>       *destructor.* Any that are not used should be declared private
>       and not defined.
>
>       If any of these is not supplied, the compiler will generate a
>       default version. Since the default is not always appropriate,
>       explicit functions should be supplied, or a comment should be
>       made indicating that the default is appropriate.
>
>       In particular, a copy constructor is recommended to avoid
>       surprises when an object is initialized using an object of the
>       same type. If an object manages the allocation and deallocation
>       of an object on the heap (the managing object has a pointer to
>       the object to be created by the class' constructor), only the
>       value of the pointer will be copied. This can lead to two
>       invocations of the destructor for the same object (on the heap),
>       probably resulting in a run-time error. The same applies to the
>       assignment operator.
>
>       Any of these that are not used should be declared private and
>       not defined, so that the compiler or linker will complain if one
>       of them is inadverdantly used or an implicit use is generated by
>       the compiler.
>
>  16.
>
>       All classes which might possibly be used as base classes must
>       define a virtual destructor.
>
>       If a class, having virtual functions but without virtual
>       destructors, is used as a base class, there may be a surprise if
>       pointers to the class are used. If such a pointer is assigned to
>       an instance of a derived class and delete is then used on this
>       pointer, only the base class' destructor will be invoked. If the
>       program depends on the derived class' destructor being invoked,
>       the program will fail.
>
>       In general, all classes should define a virtual destructor
>       unless the added size of the virtual function table pointer
>       would be unacceptable
>
>  17.
>
>       An assignment operator which performs a destructive action must
>       be protected from performing this action on the object it is
>       operating on.
>
>       A common error is assigning an object to itself (|a = a|, but
>       usually not that obviously). Normally, destructors for instances
>       which are allocated dynamically are invoked before assignment
>       takes place. If an object is assigned to itself, the instance
>       variables will be destroyed before they are assigned. This may
>       lead to strange run-time errors. If |a = a| is detected, the
>       assigned object should not be changed, e.g.
>
>       const T&
>       T::operator=(const T& rhs)
>       {
>          if (this != &rhs) {
>             delete m_t;
>             m_t = rhs.m_t;
>             // rest of assignment...
>          }
>          return *this;
>       }
>             
>  18.
>
>       A public member function must never return a non-const reference
>       or pointer to private member data or to data outside an object.
>
>       This rule may be violated by member functions which relinquish
>       ownership of an object, e.g. from container classes. In all
>       cases, it must be clear where ownership of every object resides.
>
>  19.
>
>       Do not use unspecified function arguments (ellipsis notation,
>       varargs).
>
>       Unspecified function arguments break type safety. Use overloaded
>       functions or default arguments instead.
>
>  20.
>
>       The names of formal arguments to functions are to be specified
>       and are to be the same both in the function declaration and in
>       the function definition.
>
>       Function argument names should be considered to be part of the
>       documentation of the class interface. Function argument names
>       should be chosen accordingly, and should appear in the
>       declaration as that is where the class interface should be
>       documented.
>
>       Argument names may be omitted in the declaration if the usage is
>       trivially obvious. However, this practice is discouraged where
>       it may lead to ambiguity, for example
>
>           void f(const T); // is this 'const int T'
>                            //      or 'const T x'?
>             
>  21.
>
>       Always specify the return type of a function explicitly.
>
>       Implicit typing should always be avoided. Similarly, |unsigned
>       int x;| is preferred to |unsigned x;|
>
>  22.
>
>       A function must never return a reference or a pointer to a local
>       variable.
>
>       If a function returns a reference or a pointer to a local
>       variable, the memory to which it refers will already have been
>       deallocated when the reference or pointer is used.
>
>  23.
>
>       Avoid using |#define| wherever possible.
>
>       Use inline functions (where necessary) for short functions; use
>       |const| or |enum| to define constants. Acceptable uses for
>       |#define| are to protect header files from multiple inclusion
>       and for "feature-test" defines.
>
>  24.
>
>       Avoid the use of "magic" numeric values in code; use symbolic
>       values instead.
>
>       Numerical values in code ("Magic Numbers") should be viewed with
>       suspicion. They can be the cause of difficult problems when it
>       becomes necessary to change a value. A large amount of code can
>       be dependent on such a value never changing, the value can be
>       used at a number of places in the code (it may be difficult to
>       locate all of them), and values as such are rather anonymous (it
>       may be that every `2' in the code should not be changed to a `3').
>
>       Magic numbers also provide no information about why that numbers
>       is used there. Well chosen symbolic names are much more useful
>       for the reader and maintainer.
>
>  25.
>
>       Use initialization instead of assignment wherever possible.
>
>       By always initializing variables, instead of assigning values to
>       them before they are first used, the code is made more efficient
>       since no temporary objects are created for the initialization.
>       For objects having large amounts of data, this can result in
>       significantly faster code.
>
>  26.
>
>       List members in an constructor initialization list in the order
>       in which they are declared.
>
>       Initialization lists are executed in the order the members were
>       declared in, not the order they are listed in. Listing
>       initializers in declaration order avoids any confusion.
>
>  27.
>
>       Avoid explicit casts between classes.
>
>       C style casts should be avoided at all times. Where casts are
>       necessary, |dynamic_cast| is preferred since it is type safe.
>       |static_cast| and |const_cast| may be used sparingly (but
>       appropriate use of |mutable| is preferred to |const_cast|).
>       |reinterpret_cast| should be avoided whenever possible.
>
>  28.
>
>       Do not rely on implicit type conversion functions in function
>       argument lists.
>
>       C++ is lenient concerning the variables that may be used as
>       arguments to functions. If there is no function which exactly
>       matches the types of the arguments, the compiler attempts to
>       convert types to find a match. If more than one matching
>       function is found, a compilation error may result. Existing code
>       which the compiler had allowed may suddenly contain errors after
>       a new implicit type conversion is added to the code.
>
>       Another unpredictable effect of implicit type conversions is
>       that temporary objects may be created during the conversion. The
>       temporary object is then the argument to the function, not the
>       original object.
>
>       Be careful with constructors that use only one argument, since
>       this introduces a new type conversion which the compiler can
>       unexpectedly use. Single argument constructors that should not
>       be used for implicit type conversions should be declared with
>       the |explicit| keyword.
>
>  29.
>
>       Never convert a |const| to a non-|const|.
>
>       Data members that should be modifiable even in |const| objects
>       should be declared |mutable|.
>
>  30.
>
>       The code following a |case| label or group of |case| labels must
>       be terminated by a |break| statement.
>
>       If the code which follows a |case| label is not terminated by
>       |break|, the execution continues after the next |case| label.
>       This program flow is confusing and hence should be avoided.
>
>       When several |case| labels are followed by the same block of
>       code, only one |break| statement is needed.
>
>  31.
>
>       A |switch| statement must contain a |default| case.
>
>  32.
>
>       Never use |goto|.
>
>       |Goto| breaks the control flow and can lead to code that is
>       difficult to comprehend.
>
>  33.
>
>       Do not use |malloc|, |realloc| or |free|.
>
>       In C, |malloc|, |realloc| and |free| are used to allocate memory
>       dynamically on the heap. This may lead to conflicts with the use
>       of the |new| and |delete| operators in C++, and can limit the
>       effectiveness of overloading global |new| with a custom allocator.
>
>  34.
>
>       Do not allocate memory and assume that it will be deallocated
>       for you.
>
>       However, in some places, it may be documented that an object
>       will be freed e.g. at the end of the event or end of run.
>
>
>   Recommendations
>
>   1.
>
>       Give a file a name that is unique in as large a context as possible.
>
>       [specify rule for constructing filename from library prefix]
>
>       [how does this interact with the library standard?]
>
>   2.
>
>       An include file for a class declaration should have a file name
>       of the form class name + extension. Use uppercase and lowercase
>       letters in the same way as in the source code.
>
>   3.
>
>       When possible, do not |#include| the definitions of classes that
>       are only accessed via pointers (|*|) or references (|&|).
>
>       Using a /forward declaration/ instead can reduce the number of
>       include files that need to be parsed and reduce the impact of
>       changes.
>
>   4.
>
>       Write some descriptive comments before every function.
>       [describe, provide examples]
>
>   5.
>
>       Use // for comments.
>
>   6.
>
>       Every implementation file should declare a local constant string
>       to contain the revision control system ID.
>
>       [should be in skeleton, class should have a member function to
>       dump the RCS ID to an ostream]
>
>   7.
>
>       Variables are to be declared with the smallest possible scope.
>
>       Variables should be declared as needed and with the smallest
>       feasible scope. This avoids cluttering the variable namespace
>       unecessarily, helps keep declaration and use close together, and
>       ensures that objects are destroyed (and their resources freed)
>       as soon as possible.
>
>   8.
>
>       A variable with a large scope should have a fully descriptive
>       name. Choose variable names that suggest the usage.
>
>   9.
>
>       The flow control primitives |if|, |else|, |while|, |for| and
>       |do| should be followed by a block, even if it is an empty block.
>
>       At times, everything that is to be done in a loop may be easily
>       written on one line in the loop statement itself. It may then be
>       tempting to conclude the statement with a semicolon at the end
>       of the line. This may lead to misunderstanding since, when
>       reading the code, it is easy to miss such a semicolon, or forget
>       to add braces when adding statements to the block. It is better
>       to place an empty block after the statement to make completely
>       clear what the code is doing.
>
>          // No block at all - No!
>          while ( /* Something */ );
>
>          // Single statement - No!
>          while ( /* something */ )
>             statement;
>
>          // ok
>          while ( /* Something */ ) {}
>
>          // ok
>          while ( /* something */ ) {
>             statement;
>          }
>             
>  10.
>
>       Think about alternatives before declaring friends of a class.
>
>       Friends can violate encapsulation. While there are situations
>       where friends are appropriate, their use should be limited as
>       much as possible. The use of many friends may indicate that the
>       modularity of the system is poor. When friends are used, it is
>       best to limit the scope by making particular member functions
>       friends instead of the entire class.
>
>  11.
>
>       Avoid the use of external static objects in constructors and
>       destructors.
>
>       The order of initialization of static objects defined in
>       different compilation units is not fixed by the language, so a
>       static object may not depend on the previous initialization of a
>       static object in a different compilation unit.
>
>  12.
>
>       An assignment operator ought to return a |const| reference to
>       the assigning object (usually |*this|).
>
>       Returning a |const| reference is most compatible with the
>       behavior of built-in types.
>
>  13.
>
>       Use operator overloading sparingly and in a uniform manner.
>
>       Operator overloading has both advantages and disadvantages. One
>       advantage is that code which uses a class with overloaded
>       operators can be written more compactly (and possibly more
>       readably). Another advantage is that the semantics can be both
>       simple and natural. One disadvantage in overloading operators is
>       that it is easy to misunderstand the meaning of an overloaded
>       operator if the programmer has not used natural semantics.
>
>  14.
>
>       When an operator with an opposite (such as |==| and |!=|) is
>       defined, the opposite should also be defined. When an operator
>       with associated operators (such as |+|, |-|, |+=|, |-=|) is
>       defined, all the associated operators should be defined.
>
>       Designing a class library is like designing a language! If you
>       use operator overloading, use it in a uniform manner; do not use
>       it if it can easily give rise to misunderstanding.
>
>  15.
>
>       Avoid functions with many arguments.
>
>       Functions having long lists of arguments look complicated, are
>       difficult to read, and can indicate poor design. In addition,
>       they are difficult to use and to maintain.
>
>  16.
>
>       An object in a function argument list should normally be passed
>       as a reference, unless the function stores the value, in which
>       case it should be passed as a pointer. Use constant references
>       (|const &| in the formal argument list) when possible.
>
>       By default C++, passes arguments by value. Function arguments
>       are copied to the stack via invocations of copy constructors,
>       which can be expensive for large objects, and destructors are
>       invoked when exiting the function. |const &| arguments mean that
>       only a reference to the object in question is placed on the
>       stack (call-by-reference) and that the object's state (its
>       instance variables) cannot be modified.
>
>       By using references instead of pointers as function arguments,
>       code can be made more readable, especially within the function.
>       A disadvantage is that it is not easy to see which functions
>       change the values of their arguments. Member functions which
>       store pointers which have been provided as arguments should
>       document this clearly by declaring the argument as a pointer
>       instead of as a reference.
>
>  17.
>
>       Wherever possible, allocated memory should be stored in an
>       object and deallocated in the destructor.
>
>       The ANSI |auto_ptr| template class can often be used to make
>       this automatic:
>
>       void f()
>       {
>          auto_ptr<T> p1(new T);
>          // ...
>       }
>             
>
>       The |T| pointed to by |p1| will be automatically deleted when
>       |p1| goes out of scope (when |f()| exits). This style of
>       "declaration as allocation" is very useful when exceptions are
>       used.
>
>  18.
>
>       Use |Assert| to test class invariants in the |InvariantTest|
>       member function.
>
>           * |InvariantTest| should be in the CLEO standard class skeleton
>           * |Assert| should be a template that throws an exception
>             instead of aborting. Should be incorporated into the CLEO
>             exception hierarchy.
>  19.
>
>       When overloading functions, all variations should have the same
>       semantics.
>
>       Overloading of functions can be a powerful tool for creating a
>       family of related functions that only differ as to the type of
>       data provided as arguments. If not used properly (such as using
>       functions with the same name for different purposes), they can
>       cause considerable confusion.
>
>  20.
>
>       |inline| functions only when necessary.
>
>       Access and forwarding functions may be inline if they are
>       unlikely to ever change. Excessive use of inlining will force
>       excessive recompilation when the implementation of those inline
>       functions changes.
>
>  21.
>
>       Prefer polymorphism to |switch| statements in class member
>       functions.
>
>  22.
>
>       Use |unsigned| for variables which cannot have negative values.
>
>  23.
>
>       Use inclusive lower limits and exclusive upper limits.
>
>       Instead of saying that |x| is in the interval |x>=23| and
>       |x<=42|, use the limits |x>=23| and |x<43|. The following useful
>       properties follow:
>
>           * The size of the interval between the limits is the
>             difference between the limits.
>           * The limits are equal if the interval is empty.
>           * The upper limit is never less than the lower limit.
>
>       By being consistent in this regard, many difficult errors will
>       be avoided.
>
>  24.
>
>       Do not use a bare pointer in the condition of an if statement.
>
>       Use |if (0 == p)|, not |if (!p)|
>
>  25.
>
>       Use parentheses to clarify the order of evaluation for operators
>       in expressions.
>
>       There are a number of common pitfalls having to do with the
>       order of evaluation for operators in an expression. In doubtful
>       cases, *always* use parentheses to clarify the order of evaluation.
>
>  26.
>
>       Avoid global data.
>
>  27.
>
>       Use standard library functions.
>
>
>   Portability Recommendations
>
>   1.
>
>       Code that requires a type of a particular size should typedef a
>       local type from a system typedef of the appropriate size. Do not
>       assume that the built-in types have particular sizes.
>       [cleotypes.inc?]
>
>   2.
>
>       Use explicit type conversions for arithmetic using signed and
>       unsigned values.
>
>   3.
>
>       Do not assume that you know how an instance of a data type is
>       represented in memory.
>
>   4.
>
>       Do not assume that |long|, |float|, |double| or |long double|
>       types may begin at arbitrary addresses.
>
>   5.
>
>       Do not depend on underflow or overflow functioning in any
>       special way. [what can one depend on?]
>
>   6.
>
>       Do not assume that the operands in an expression are evaluated
>       in a definite order. [value modified twice, functions with side
>       effects]
>
>   7.
>
>       Do not assume that you know how the invocation mechanism for a
>       function is implemented.
>
>   8.
>
>       Do not assume that static objects in different files are
>       initialized in any special order.
>
>
>   Style Recommendations
>
> Programming style is to some extent a matter of individual taste that 
> should not be dictated by inflexible rules. However, there are 
> advantages to a common style for a large collaborative group, or a 
> recommended style for inexperienced programmers. Accordingly, CLEO 
> members are encouraged to consider these recommendations.
>
>   1.
>
>       The style within a single module *must* be consistent. Where
>       choices are allowed, one option must be chosen consistently
>       within a module. *Always* respect the style decisions of the
>       original author.
>
>       This is the only absolute requirement in this section.
>
>   2.
>
>       Class names should begin with an uppercase letter.
>
>   3.
>
>       Class member functions should begin with a lowercase letter.
>
>   4.
>
>       Class member variables should begin with a distinguishing
>       prefix. "|m_|" is recommended; a single leading underscore is
>       /not/ recommended.
>
>   5.
>
>       Constants should begin with a lowercase |k| or be all uppercase.
>
>   6.
>
>       In names composed of more than one word, subsequent words should
>       be distinguished by an uppercase letter or a separating underscore.
>
>   7.
>
>       Do not use spaces around `|.|' or `|->|', nor between unary
>       operators and operands.
>
>   8.
>
>       Declare only one variable per line. The dereference operator
>       `|*|' and the address-of operator `|&|' should be directly
>       connected with the /type names/ in declarations and definitions.
>
>       The characters `|*|' and `|&|' should be written together with
>       the types of variables instead of with the names of variables in
>       order to emphasize that they are part of the type definition.
>       Instead of saying that |*i| is an |int|, say that |i| is an |int*|.
>
>       Traditionally, C recommendations indicate that `|*|' should be
>       written together with the variable name, since this reduces the
>       probability of making a mistake when declaring several variables
>       in the same declaration statement (the operator `|*|' only
>       applies to the variable on which it operates). Since the
>       declaration of several variables in the same statement is not
>       recommended, such a advice is unneeded.
>
>   9.
>
>       Indentation should follow the Ellemtel style as implemented in
>       emacs |cc-mode.el| version 4.85 or later. This can be selected
>       by adding this elisp:
>
>       (add-hook 'c++-mode-hook
>       	  (function
>       	   (lambda ()
>       	     (c-set-style "Ellemtel")
>       	     (c-set-offset 'statement-case-intro '+)
>       	     )))
>             
>
>       to your |.emacs| file.
>
>           * Ellemtel style selects a basic 3-space indent.
>           * Function declarations should have the return type on a
>             separate line, with the left parentheses immediately after
>             the function name.
>           * Braces should line up in the same column, or optionally
>             the left brace may follow the statement that begins the
>             block, with the right brace lined up with the left edge of
>             that statement.
>           * Access control labels inside a class declaration are
>             indented, and member function and data declarations are
>             indented yet another level.
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Halld-offline mailing list
> Halld-offline at jlab.org
> https://mailman.jlab.org/mailman/listinfo/halld-offline

-- 

------------------------------------------------------------------------
 David Lawrence Ph.D.
 Staff Scientist                 Office: (757)269-5567   [[[  [   [ [       
 Jefferson Lab                   Pager:  (757)584-5567   [  [ [ [ [ [   
 http://www.jlab.org/~davidl     davidl at jlab.org         [[[  [[ [[ [[[
------------------------------------------------------------------------





More information about the Halld-offline mailing list