C++ Standards

Pages: 12
Hi there,

What coding standards are most important to you? I'm doing a review and would like to get some feedback.

Naming conventions, is m_ used these days?
Do people prefer to use == NULL or == 0?

Any feedback would be great.

Thanks.
I barely ever put m_ when using data members.

Never use NULL either; always use 0.

Most classes I create either begin with a 'C' or are all in lower-case letters.

I omit void in function prototypes (rather, parameter specifications, but whatever).

Mostly use Allman for my indent style.

I tend to use std::endl instead of \n in cout calls.

Probably more things that I can't think of at the moment.
m_ is an evil style in my book.
I normally use NULL to distinguish between pointer and integer, but I'll occasionally use 0 when I'm feeling lazy.
I use \n
void in empty function prototypes does nothing, so I don't bother with it.

I haven't done enough research to name my indentation style, so maybe someone else knows what it is.

1
2
3
4
5
6
7
8
9
10
#include <cstdio>

int main(){
    int count;
    for(count=10;count>0;--count){
        printf("%i, ",count);}
    printf("FIRE!!!");
    getchar();
    return 0;}

In my coding style, I tend to use as little whitespace as possible (I like how compact it looks).
Looks like a variation on 1TBS (The One True Brace Style); the only difference with normal 1TBS is that you put the trailing brace on the same line too.

Reference:
http://en.wikipedia.org/wiki/Indent_style
The best coding standards talk nothing about source code formatting or conventions because what looks
good to one person looks terrible to the next. I prefer "C++ Coding Standards" by Sutter & Alexandrescu,
ISBN 0-321-11358-6. Note that my statement comes from Rule 0 in the book.

(Though I will say, PiMaster, that your "no whitespace" approach probably will win you far more enemies
than friends).

In C++ it is probably better to compare pointers to 0 than NULL, though an alternative is to eschew the
debate and do:

1
2
if( ptr ) // ...
if( !ptr ) // ... 


C++0x will solve the NULL problem by adding nullptr.

And Kyon, because std::endl also flushes the stream, under some circumstances (albeit rare) this can
lead to a performance problem.

+1 to everything jsmith said, except I'm not familiar with that particular formatting style he mentioned.

In particular, I often do if(ptr) and if(!ptr). Though I tend to do that with all integral types, not just pointers.

I tend to favor this:

1
2
3
4
5
6
7
8
9
10
11
void function()
{  // braces on their own line
    SomeStuff();
    MoreStuff();

    // whitespace to separate different "steps" or "groups" in the function
    //   makes following the logic more clear
         if(something <  4)   Foo();  // small one-liner conditionals put on 1 line if there's several
    else if(something < 15)   Bar();  // indented consistently for clarity
    else                      Baz();
}

Last edited on
I don't tend to prefix or suffix my variables.

I always use 0. I never liked NULL. 0 feel cleaner ;o)

Small classes that are general purpose 'tools' I tend to name in lower case:
1
2
3
class stream_filter
{
};


When it comes to business objects that perform a specific logical function for a particular application I generally use CamelCase names:
1
2
3
class CustomerManager
{
};


There is no 'correct' way to format code, but there are one of two ways that I feel are 'incorrect'. But not many. As long as its readable and neat then I don't care. I also tend to use Allman for indentation. I don't do gaps before braces and carefully manage gaps inside the braces like this:
 
void func(int a, int b, int c); // one space after comma, no other spaces. 


I always use braces on ifs and whiles. I tried quitting but I just can't stop myself. If it is a single instruction I will often put it on the same line:
 
if(condition) { do_stuff(); } // braces for safely 


I always use '\n' rather then std::endl unless I want to flush the stream. Sometimes I want to flush the stream without ending the line so I use std::flush.

At the end of the day I think the important thing is that the code looks neat and tidy with no superfluous stuff lying around. If the code looks good then it probably is because the author obviously cared ;o).

EDIT: Oh and I do if(ptr) all the time. I never do if(ptr == 0). If I have to test if a std::string is not empty even I will do if(my_string.length()) { do_stuff_with(my_string); }

EDIT 2:

Also a associate pointers and references to the type (left):
1
2
3
int* iptr;

std::string& str;
Last edited on
And Kyon, because std::endl also flushes the stream, under some circumstances (albeit rare) this can lead to a performance problem.


The performance can only be noticed when you cout say at least a million times. So for pre-generation programs that are supposed to do large volume data, the \n do play a part although most of the times it is not even noticeable to human eyes.
closed account (1yR4jE8b)
I like Netbean's code formatter, I set the style to the built in 'Ansi' style and just hit 'alt-ctrl-f' and my IDE takes care of everything for me.

Being anal retentive about where your braces are is dumb, CONSISTENCY is more important, which is why I like the auto-formater.
jsmith wrote:
The best coding standards talk nothing about source code formatting or conventions because what looks
good to one person looks terrible to the next. I prefer "C++ Coding Standards" by Sutter & Alexandrescu,
ISBN 0-321-11358-6. Note that my statement comes from Rule 0 in the book.


Here's an online example of coding standards (similar to the book mentioned above). I thought it would make a nice example for what coding standards really are:
http://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=637


Last edited on
@Galik: string::empty() is probably a better way of determining "emptiness" than length(),
since in theory empty() needn't count all characters, but length() does. Having said that,
I looked at gcc's implementation of those functions are they are pretty much identical.
Though I'm not sure what the standard says about the required runtime complexity of
the two methods (empty() should be constant, length() could be O(n) or constant).
But anyway, IMHO empty() is more expressive than length() in this case.

@sohguanh: I think it depends upon your processor. I think the best approach is either
to use std::endl when you know you want to flush the stream, or use '\n' and then use
std::flush appropriately. Neither is easier to get right as a programmer, as both techniques
require the same amount of diligence on the part of the programmer.

@Disch: I agree -- when testing for integral zero, I use the same technique if( myInt )
and if( !myInt ). Also for boolean, but in that case explicitly testing for true can lead
to subtle bugs. if( flag ) and if( !flag ). This reminds me of the old days
of Borland's compilers where if you dared write if( flag == false ) it would actually
generate hideous code: load flag into a register, test it for zero (ie, set the condition codes), set
the register to 1 if true, 0 if false, then compare the register against false (0) _again_, then branch.
There was a completely unnecessary compare in there. And that is why I stopped writing
if( flag == false ). Because of implicit int-to-bool conversions, of course, one should
never write if( flag == true ) lest flag be of a type other than bool.




@jsmith I agree std::string::empty() is a much better choice. I was looking for an example of a non-bool. However it did not occur to me that std::string::length() would have to count all the characters. I just looked at the standard and for containers size() is supposed to be constant time. Now I assumed a std::string was a container and that std::string::length() would simply do what size() does for containers. But according to the standard std::string::size() calls the char_traits length() function which should run in linear time. That suggests that it is assumed the characters will be counted.
My reason to prefer empty() to length() or size() is just habit. Vector and string are the same cost; not so for other containers. I'm less likely to use size() == 0 on a list or set.
I would be downright horrified if size() or length() actually iterated through and counted all the elements for any container.
I'm sure that most containers' size() methods iterate, except for perhaps std::vector<> which can use
pointer arithmetic. (Reason being is that you pay the penalty of an extra data member to keep track
of the element count, even if you never call size().)

(Just looked up gcc's implementation of std::list<>::size(), and it does std::distance( begin(), end() )
which is going to be linear for any iterator that isn't random access).
PiMaster won me as a friend with his no-whitespace approach. His posts get a full ack from my side.

The most important thing to me is that people use tab idents instead of multiple spaces! I will never ever write code like that. Also, I disagree with the "Do not declare more than one variable per declaration" rule. In one of the links in this thread it said:
Every declaration should be for a single variable, on its own line, with an explanatory comment about the role of the variable.

I'd rather write:
1
2
3
4
struct v3f {
	float x, y, z;
	...
}

than:
1
2
3
4
5
6
struct v3f {
	float x; // Holds the x coordinate
	float y; // Holds the y coordinate
	float z; // Holds the z coordinate
	...
}
I must say I agree with the "only one single variable per line"-'rule', but I'd like to make an exception (like JoR already pointed out):
Every declaration should be for a single variable, on it's own line, with - optionally - an explanatory comment to go with it. This does not apply to variables that have a self-explaining name or where their contexts is known (like in a structure or class).
I hate tabs.
Why, Duoas, may we ask?

As for multiple variable declarations in one line, I do it only if the variables are in some way related. Just putting it out there.

-Albatross
Generally because tabs can be different on different systems. (i.e. 4 spaces on one and 6 on another). I use tabs anyway :P although some IDE's have an option to automatically convert tabs to spaces for you.
Pages: 12