PDA

View Full Version : Codestandard



Angeleon Askaroth
05-22-2007, 11:16 AM
Code structure:
* intendation should be three whitespaces per step. The use of tab is not preferred as it varies between editor.
* Wherever it is applicable, the { should be on the row directly below its owner.
* if there are a lot of intendations in a code, consider writing a subfuction to replace them.
* Avoid longer functions. Should it seem to get out of hand, write a subfunction to handle some of the rows.


Functions:
* the first word should start with a lower-case letter, but the remaining words should have the first letter upper-case. I.E: aGoodName();

Classes:
* the names of classes has the same structure as functions, except it also starts with a upper-case. ThisIsGoodClass
* Get and Set functions should be the standard for accessing variables. Making them inline is also a good habit(might not make any real difference, but the effort isn't big anyway).
* all the membervariables will begin with a m (for member) followed by a underscore. then start the first word with a lowercase while the following are upper-case. m_goodNameThisIs;
* all memberfunctions should be started with a small letter in the first words followed by uppercase first letters of the rest of the words: functionOne()
* Const functions should be used if possible.
* { should be under the class name.
* public, private and protected should be at the same level as the { for the class.
* Get and Set functions can be fully withing the class definition, but otherwise functions should be defined in a seperate file.

Documentation:
* Every class-definition file (.h) should have a document header explaining what the class does and any important information. First thing in the file.
* Every functions should have a simple one-line comment that will explain it briefly.
* Use english (obviously.;))
* Rule of thumb: Comment one line for every for, switch or while-loop and when there's something advanced or cryptic.


-----------------------------------------------------------------
Example (Foo.h)
-----------------------------------------------------------------
/*
* Filename: foo.h
* History:
* pA1 2004-02-23 Benny Created
* pA2 2004-02-25 Leo Added func.
* A 2004-02-26 Daniel Completed
*
* Foo creates a virtual puppy that you can kick at will
* with the function kickPuppy(int x) where x should not
* be four becuase then it will eat you.
* It will handle the graphics and physics of the puppy,
* but the sounds is not handled in this class. It will
* call a class to handle that.
*
* Oh, and it calculates string Theory.
*
*/
#ifndef FOO_H
#define FOO_H

class Foo
{
public:
// Constructor that creates the object.
Foo();

// The destructor
virtual ~Foo();

// Performs string theory math.
int bar();

// Performs even more string theory math.
int barImproved();
};
#endif
-----------------------------------------------------------------
Example (Foo.cpp)
-----------------------------------------------------------------
#include "foo.h"

int Foo::bar()
{
if ( 6 > 7 )
{
return 0;
}
else
{
return 1;
}
}

Foo::Foo()
{}

Foo::~Foo()
{}

int Foo::barImproved()
{
return ( 1 * 1 );
}

Alright. This sounds like a good start right? Any comments or preferences that I should take into consideration? Personally, this is what I've been using for a while, but I've always been flexible so changing anything or all of it isn't a big deal. Besides, no one will kill you for not following it properly. =)

I'm not big on commenting, I always find that you can spend the time better on other things. Like sleeping, so there's no need to do anything more than basic commenting like I mentioned above.

Anything else?

Thirlan Tyrandor
05-22-2007, 07:53 PM
Emphasis should be placed on using unsigned longs whenever possible and to avoid ints and floats. Ints are system specific in C/C++ so they can change based on the system and floats require more computations than an int and can result in floating point errors caused by rounding errors.

Also whenever possible, domain limits or variable sizes or anything that is a constant should try and be a power of 2. If you have an array that has a constant size of 23 then make it 32. Powers of two are better handled by computers. For instance the human eye sees 24-25 frames per second but for purposes of the project we should use tick increments of 32 and/or 16 since we can divide the frames in micro seconds better if they are divided in powers of two. The Patriot missile system tried to divide the time frames in 1/10ths of a second. 1/10 in floating points is 0.011111111111111 in binary or in otherwords it's 0.09999999999. The error here seems really small (only 0.0000000001) but after an hour, or 60*60*100 = 360,000 of these increments, the error starts to grow rather large.

Lastly all functions should be in a class and for the following reasons. All functions (within reason) should have a frequency variable that counts the number of times the function has been called as well as a cpu execution time variable that computes on average how long a function runs before it exits. This also means that all functions should be properly formed and should have only a single entry and exit point, which means there should only be one return in a function and a function should always return something. It is also important that we create automated unit testing functions for each function.

Doing this will help us later by insuring the following:

- Single entry and exit point will help minimize flow analysis of the program for debugging.
- Frequency and average cpu counting will help us see which functions are used the most and require the most optimization (frequency * average cpu run time).
- The frequency alone will also help us figure out the priority of debugging. Functions with the highest frequency and/or the most likely to execute should be checked in debuged first since they will result in better MTTF scores (mean time to failure)
- Automated unit regression testing will help us auto-test and debug the most basic issues we have with our program and more importantly it can run entire tests during the nights so that when we come back in the morning we know where the bugs are and combined with the frequency and runtime it can print us a list of which ones to debug first. It will also tell us if we broke old pieces of the code when we introduced new ones, hence the name regression testing.

It should be noted that not all functions should have frequency and average cpu run times. For instance ultra basic get functions shouldn't since it's one line of code and we could careless.

Angeleon Askaroth
05-22-2007, 08:50 PM
The two first points are both valid, but are more of an issue for applications with heavy requirements for time, and a game rarely has that. Though I do think it is a good standard to have, it is nothing that will matter in the long run for a game of this size.

Testing is the most time-consuming part of a development cycle, and that would help thoroughly. For the frequency and time thing we should create a class that handles that so that we won't have to rewrite the same code all the time. A simple class that'd make that easier shouldn't be too hard, right?

Just for the record, I hate testing :), but I do see the need in a project of this size.

Surly von Fishbarrel
05-22-2007, 10:56 PM
int Foo::bar()
{
if ( 6 > 7 )
{
return 0;
}
else {
return 1;
}
}BOOO!!!!



int Foo::bar() {
if ( 6 > 7 ) {
return 0;
} else {
return 1;
}
}So much more neat and tidy :)

Is there any reason people don't just drop off the curly braces for single-line conditional statements?


int Foo::bar() {
if ( 6 > 7 ) return 0;
else return 1;
}

I mean, convention aside... is there a performance reason for that?

Angeleon Askaroth
05-23-2007, 06:46 AM
No performance reason, but becuase there are several developers on a semi-advanced project, readability is worth alot, and when it is compressed as in your example, the more advanced passages are going to be completely unreadable.

Thirlan Tyrandor
05-23-2007, 07:53 AM
Not to mention it's also safer coding wise...

Surly von Fishbarrel
05-24-2007, 03:20 AM
Not to mention it's also safer coding wise...What does that mean?

Thirlan Tyrandor
05-24-2007, 07:08 AM
It's considered risky to program without brackets. The lack of brackets wont make your code explode but it means you have a higher chance of committing an error. For instance let's look at this tiny snippet of code and let's assume it's in a HUGE block of code.

setSize[root] = 1<<a;
if(c < root && zeta < root && zeta > c || setSize[root-1] > setSize[root+1]) c++;
root = c%a;

Right right now you can easily tell but as the code starts to increase it gets messy and things aren't so obvious, one is bound to make the oversight of not noticing the c on the end of if statement and one might assume "root = c%a" is the actual executed statement for the if.

Another example is assume two people are editing the code, which is going to happen as we work together, and one person doesn't use brackets for short ifs. As the versions of the file grows you may not be entirely sure what a person was doing and there is a chance that a piece of code ends up looking like

if(c < root && zeta < root && zeta > c)
c++;
root = c%a;

When it was meant to be

if(c < root && zeta < root && zeta > c)
{
c++;
root = c%a;
}

and since both of you were working on it neither of you can fully figure out what's going on and you both scratch your heads trying to find the error.

Surly von Fishbarrel
05-25-2007, 12:02 PM
So no one ever under any circumstances codes without curly braces on conditional statements when working in a team environment? I can understand your reasoning, but I don't think it's less safe if it's part of the code standard unless you can't recognize a semi-colon for some reason... and in that case you're just a retard. I'm just asking because when I was working on a NWN mod with a team of people years ago I did some scripting for them for basic things and their code format used no curly braces on short if statements. They all seemed to be professionally educated, but I'm hardly experienced working with many different team-environments so I want to know if it's just ridiculous to try that or not.

I think they also began all variables with a lower-case letter signifying the data type "iVariable, nVariable, sVariable, etcetera"

Is that common, or not?

Angeleon Askaroth
05-25-2007, 12:24 PM
When not using the brackets on short statements, the risk is not that it will happen a lot of the time. The risk is that it can happen, even if it is just once. That kind of error is nearly impossible to find and will cause hours of debugging when instead you could just have used brackets. It has nothing to do with professionality or skills whatsoever, but more to the fact that people are still human. They make mistakes and this is one that could easily be avoided. Hence a good policy.

I've not seen that naming-scheme, to be honest, but it probably isn't all too uncommon. I suspect it is something that started in another language and was brought over to C/C++ by someone as it would be more useful in an environment without types, like PHP.

I wouldn't push that convention on anyone while programming in C as I don't think it matters, but again, it is just a simple addition and if there's an advantage to it, why not?

Surly von Fishbarrel
05-25-2007, 12:28 PM
Is the new line for the opening curly brace more common than not? I have to say it grinds against my compulsion pretty effectively. Maybe I should just get used to looking at it that way :P

Angeleon Askaroth
05-25-2007, 12:32 PM
No, probably equally common. I see both used rather regulary and I just chose the one I use the most. I tend to mix them though, when I program alone, as it hardly matters. The point is for the code to be alike no matter who wrote it so that everyone can review anyone elses code. We could easily change it to have the bracket next to the statement instead of below it.

Surly von Fishbarrel
05-25-2007, 12:38 PM
Yeah, I'm all for standards and such. Easier to read, blah blah blah. I like it, I'm just questioning what's common and what's not since I really haven't worked in many team environments before (which probably means that out of laziness and knowing myself really well that I become sloppy with my own code that no one else reads).

In fact I've only really been attempting to adhere to common standards since I started learning Actionscript 3.0 "the right way" :P