Help:Formatting

From SA-MP Wiki

Jump to: navigation, search

When writing articles with code please ensure that the code is formatted consistently for readability. The exact choice of formatting style you use is up to the author, the "which formatting style" debate is almost as old as coding itself so to try and enforce one is next to impossible. An example of a formatting style is given below if you're not sure of what to use:

#define SOME_DEFINE (5)
 
stock FunctionName(parameter, list[])
{
	new
		nVariable1 = 7,
		variable2;
	static
		sVariableNumberThree[3];
	if (Function() == 1 && nVariable1 - SOME_DEFINE < 10)
	{
		OtherFunction(sVariableNumberThree, sizeof (sVariableNumberThree));
	}
	else return -1;
	switch (nVariable1)
	{
		case 'a':
		{
			DoSomething(1, 2, 3);
		}
		case 0, 1, 2:
		{
			DoSomething(4, 5 * nVariable1, 8);
			Another(1);
		}
		case 4 .. 6:
		{
			for (new i = 0; i < 10; i++)
			{
				if (CheckVar(i))
				{
					printf("checked: %d", i);
				}
			}
		}
		default:
		{
			new
				Float:fVar;
			fVar = float(nVariable1);
			fVar *= 2.5;
			goto ret_addr;
		}
	}
	ret_addr:
	return (variable2) ? (nVariable1 * 7) : (0);
}

The code above combines a number of different features to consider formatting for. Some of these are explained below.

  • Keywords such as "if" and "sizeof" have a space between them and the opening bracket of their parameters. This is to differentiate them from functions which don't.
  • There should be no space between the opening bracket and the first symbol contained within, or the last symbol and the closing bracket, unless the statement is spread across multiple lines.
  • The semi-colon at the end of a line should come immediately after the statement, i.e. no space.
  • Empty statements ({}) should be separated from the control structure with which they're associated by one space, however the whole thing should be on a single line (again, excepting multiple line statements).
  • Braces are on a new line in line with the control structure which they go with to make code easy to read when scanning through.
  • Indentation is done one tab in from an opening brace, and one tab back at a closing brace.
  • Single line statements should come after the control structure which they go with for clarity. However this style is discouraged and single line statements should generally be done using braces for clarity and ease of modification.
  • Variables are declared on separate lines for clarity of number and so variables initialised at declaration, arrays and tagged variables are aligned with regular variables.
  • No variable should be declared on the line with the declarator, when using 4 space tabs "new" variables are in line but the size of a tab cannot be guaranteed and other declarators such as "static" will cause the first variable to be misaligned. The exception to this is a for statement when the variable declaration comes within the for statement.
  • Operators (*, ==, && etc) should have a space to either side of them.
  • Lists should be separated by a comma followed by a single space.
  • Only one statement (code ending with a semi-colon) should exist per line, the obvious exception again being a for statement which contains three statements in one.
  • Functions should be named with all words within the name starting with a capital letter.
  • Variables should have all words in their name start with a capital letter except the first.
  • It is generally advisable to prefix the variable name with a descriptor to make it easier to understand what a variable is without looking back to the declaration. Examples include s for static, f for float or f_s (or s_f) for static float, i or n for integers (although these would be the most obvious ones to not prefix). If a prefix is included it counts as the first word in the name for capitalisation purposes.
  • If you're prefixing strings use sz, not s, to not confuse them with statics, sz stands for "string zero", indicating it's null terminated (i.e. ends in zero).
  • Global variables should ALWAYS be prefixed with a g, this helps reduce the chance of shadowing problems and helps describe the scope of the variable.
  • Constants and defined numbers should be written entirely in capitals with words separated by an underscore.
  • Labels should be written entirely in lower case with words separated by an underscore.
SOME_SYMBOL // Define
someSymbol  // Variable
some_symbol // Label
SomeSymbol  // Function
sSomeSymbol // Static variable
gSomeSymbol // Global variable

Examples of different types of symbol showing how the type can be determined simply from the name.

  • Description comments should have at least a space between the comment open (and comment close if applicable) and the text.
  • Commented out code should not have a space between the comments and the code.
  • Code commented out for purely debugging purposes should have the comment characters at column 0.
{
	SomeFunction(); // Call SomeFunction()
	//RemovedFunction();
//	TemporarillyRemoved();
}

Examples of different types of comment showing how the spacing can help with for example debugging by differentiating code you don't want and code you've only removed temporarily to test something (so you don't forget to put something back).

  • #if/#else/#endif should be treated as braces for indentation purposes.
  • Preprocessor directives should follow current indentation.
#if !defined SOMETHING
	#define SOMETHING (7)
#endif
 
if (bla)
{
	#if SOMETHING == 7
		print("7");
	#else
		print("not 7");
	#endif
}
  • There should be no spaces surrounding the colon in a tag variable declaration.
  • There should be at least a space after the colon on a case statement however braces are encouraged a described above.
  • There should be no code on the same line as a label.
  • It is advisable to initialise variables explicitly in the declaration. This is not required for variables which will be set to 0 in PAWN however it is best practice for conversion to other languages.
new
	var1;
var1 = 3; // var1 will be set twice, to 0 then 3
 
new
	var2 = 3; // var2 will only be set once
 
new
	var3 = 0, // Does not require defining explicitly but wastes no time and clarifies code
	var4 = SomeFunc(); // Set the variable to a function return
 
static
	sVar5;
sVar5 = SomeFunc(); // Static variables cannot be initialised with a function but are only zeroed once anyway.
  • Variables should be declared for the smallest possible scope in which they are required.
  • Variables should be declared in a single statement where possible.
  • Defined numbers should be enclosed in brackets to ensure precedence. As should define variables where possible.
  • Code in a define statement should be spread out as if it was real code using \. The \'s should be lined up.
  • Variables in a define statement should be prefixed by an underscore, a representation of the define's name and another underscore then the name to reduce the chance of non-obvious variable shadowing or redeclaration problems. Their scope should also be restricted to the define. The leading _ separates them in naming style from labels.
#define SOME_NUMBER (5) // Number enclosed in brackets
 
#define SOME_CODE(%1) \
	((%1) * 2) // Variable enclosed in brackets
 
// Note the lack of braces below so the code ends on a semi-colon
#define LONGER_CODE(%1,%2)					   \ // Items not separated by a space due to define statement restrictions
	for (new _lc_loopVar = 0; _lc_loopVar < 10; _lc_loopVar++) \ // \'s lined up
		printf((%1), %2)
/*
%2 has no brackets to collect all additional parameters, so:
 
LONGER_CODE("hi %d %d", 4, 5);
 
will compile to:
 
for (new _lc_loop = 0; _lc_loop < 10; _lc_loop++)
	printf(("hi %d %d"), 4, 5);
 
Whereas brackets would produce:
 
for (new _lc_loop = 0; _lc_loop < 10; _lc_loop++)
	printf(("hi %d %d"), (4, 5));
 
Which will not compile
*/
  • An exception to the brackets in defines is if you are using the define in a stringize token. You need to be careful that you can ENSURE the define will only be a simple number.
#define NUMBER (5)
print("NUMBER = " #NUMBER); // Will produce an error
 
#define NUMBER 5
print("NUMBER = " #NUMBER); // Won't produce an error

Remember you do not have to follow this style but please ensure whatever style you use is consistent, a common mistake people make is to do something like:

function(par1,par2, par3);

Where obviously there is no space after the first comma but there is one after the second.

These formatting rules are not finalised, please see the discussion page.