Re: C++ Coding Style

Chris Frey <[email protected]> Sat, 20 Dec 2003 14:33:46 -0500
Newsgroups gmane.linux.zynot.devel
Message-ID <[email protected]>
The person doing the most coding should probably have the right to set
the rules.

That said, here are a few comments. :-)

On Sun, Dec 21, 2003 at 12:03:55AM +0800, Low Zhen Lin wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Since we are about to begin coding, I thought it might be wise to
> declare the style conventions.
> 
> Here are mine:
> 
> 4 spaces per tab.

Using space characters or tab characters?  I think tab characters are
more flexible, and allows the programmer to set his editor to display
the number of "spaces" the way he likes it.

> ... one space after branch control:
> 
> ~    if (i < 0)
> 
> ~    while (true)

You didn't give a reason why for this format, but I prefer:

if( blah )
while( blah )

because if nested parentheses are needed, it is more visually clear:

if( (blah && foo) || (wince && flex) )

Also, if line wrapping is required, it lines up better:

if( some_gigantic_statement == 5 &&
    another_gigantic_statement == 6 )
{
    ....;
}

> '*' attached to typename, no spaces in declaration:
> 
> ~    const char* cstring;
> ~    int (*pfunc)(int, int);

This I disagree with because it leads to confusion in declarations of
lists of pointers.  Which is correct?

    char* ptr1, ptr2;
or
    char *ptr1, *ptr2;           // correct

Keeping the star with the variable keeps things clear.

> '[]' attached to identifier, no spaces, always:
> 
> ~    int array[16];
> ~    int matrix[8][8];
> ~    int 3dSpace[4][4][4];

Another thing to consider might be when you have math in the array:

    array[a+b];

I think the more complicated the array index is, the more spaces should be
used, for readability:

    array[ getHash() << 8 ];

> CamelCasing for type names, smallFirst for instance names:
> 
> ~    RadioButton radioButton;
> 
> ~    void onClick(double, double);
> ~    // onClick is an instance of void (*)(double, double)

What about class member names?  Do you prefix with 'm_' or suffix with '_'?

> Labels at previous indent level:
> 
> ~    int main()
> ~    {
> ~        int i = 0;
> ~    LoopTop:
> ~        cout << "i = " << i << endl;
> ~        i++;
> ~        if (i < 16)
> ~            goto LoopTop;
> ~        return 0;
> ~    }

Labels are used so infrequently, and have no compiler control over where
they may be called (i.e. indentation could imply something incorrect),
that I prefer them always on the outer margine.  It makes them glaringly
obvious.

> ~    class Object
> ~    {
> ~        public:
> ~            explicit Object();
> ~        protected:
> ~            unsigned int refCount;
> ~        private:
> ~            Object(Object&) { }
> ~    };

This looks new to me, and wastes precious screen space.  I think public,
protected, private should be along the class's '{' column, and the members
in one indent.

    class Object
    {
    protected:
        int member_;

    public:
        Object();
    };

> '.c++' for C++ source code. 'cpp' is the C preprocessor, damnit! 'cxx'
> is for badly designed filesystems. 'cc' is the C compiler, not the C++
> compiler. 'C' is indistinguishable from 'c' on Mac OS X (HFS+) and
> Windows and other 'user friendly' OSes.
> '.h' for C and C++ headers. cpp thinks they're the same.

This is a taste issue, but I think .cc makes perfect sense for C++ code.
I like .h for C and C++.  The shorter names help save screen real estate
when you're looking at a directory listing, or some other file list.

> C++ class files and their headers go into the same directory.
> One class per header.
> Directory structure reflecting namespace:
> 
> ~    // to get Siphonophora::ComponentKit::Core::Object
> ~    #include <Siphonophora/ComponentKit/Core/Object.h>

Excellent.  And keep any reuseable headers in their own directory, to help
avoid filename clashes:

    #include <Core/Types.h>
    #include <Linux/Types.h>

Include any headers that are in the same directory with the "" syntax,
to help flexibility if they need to be moved.  For example, if you have
test1.cc and test1.h in Core/, and you need to move it to System/, the
following include in test1.cc would be harder to alter than the second one:

    #include <Core/test1.h>     // would need to edit this
    #include "test1.h"          // needs no editing

> British spelling:
> 
> ~    ColourPicker colourPicker;

Being Canadian, I have no problem with this, but I'm sure others will. :-)
As long as it is consistent.

> No publicly accessible variables. Use set/get instead. (Yes, I know it
> is slower, but - you can inline it, and the object is notified if
> someone changes the variable. Also more flexible about storage of the
> variable.)

I agree with this.  One thing to note is that if you have a structure
inside your class, you can return a const reference with the same effect:

    struct A
    {
        int member;
    };
    class Object
    {
        A a;
    public:
        const A &getA() const { return a; }
    };

And saves typing all the struct members.

Good list!

- Chris