MINX Style Guidelines - GearChicken/MINX GitHub Wiki

C++

Spacing

Operators

Assignment should have one space between the variable, the =, and the assignment.

int a = 1;

Standard math operators (with the exception of division), bitwise operators, logical operators, and ternary should have one space between the operator and the operands.

a + 6
b - c
d * f
f << 4
g | 1
f || x
x && y
x ^ r
a ? b : c

Division, as an exception, should not have spaces between the operator and the operands

b = a/c;

Unary operators, prefix or postfix should have no spaces between the operator and the operand. In addition, whenever it is possible use the prefix version of an operator, instead of the postfix version.

*b
&a
++i
!c
~d

Parentheses, even if they are unnecessary, should be used if they increase readability.

Pointers

When declaring a pointer, the asterisk should be next to the type.

const char* text;
int* b;

instead of

const char *text;
int *b;

**Note that this is different from the dereference operator, which should be next to the variable **

	int* b;
	int a = *b;

instead of

	int *b;
	int a = * b;
Pass by Reference

When using an argument to a function with pass by reference, the ampersand should be next to the type

	void SomeFunc(Vector2& v);
Spaces

Use tabs for indentation. Do not use spaces.

Braces

Put braces on the next line, * everywhere * (if, else, functions, structures, class definitions, etc.)

if(x)
{
// Code
}

The else statement starts on the next line after the last closing brace.

if(x)
{
// Code
}
else
{
// More code
}
Parenthesized expressions
x = (y * 0.5f);

Instead of

x = ( y * 0.5f );
Templates

There should be no spaces between the brackets, except to adhere to other rules

vector<int> a;
vector<int*> b;
vector<int*>* c;
vector<vector<int*>> d;
vector<vector<int*>*> f;
vector<vector<int*>*>* g;
SomeFunc<int>(a);
Newlines

Empty lines should be placed to separate segments of code, but more than one should not be placed in sequence. Some reasons to place them include separating multiple class methods in a .cpp file, separating multiple enums/structs/classes within one header, and separating sections within a method.

A::A()
{
...
}

void A::B()
{
...
}
enum E
{
...
};

Class C
{
...
};
double SomeFunc(Vector2 v)
{
	double sqrt2 = sqrt(2);
	double sqrt3 = sqrt(3);

	Vector2 sqrts = Vector2(sqrt2, sqrt3);

	return v.Dot(sqrts);
}

Casting

Casting should be done with C++ style casts

Floating Point Precision

Use double precision specification for floating point values unless there is an explicit need for a single precision variable (such as interacting with other libraries).

double f = 0.5;

Instead of

float f = 0.5f;

Don’t put any more zeroes (or too few) into a float than necessary for readability, for example:

float f = 1.0f;
float g = 0.5f;

Instead of

float f = 1.00f;
float g = .5f;
float h = 1.f;

Naming Conventions

Functions

Member function names start with an Uppercase (and then follow Pascal Case)

void Class::Func();

In multi-word member function names, each word starts with an upper case.

void Class::ThisFunctionDoesSomething();

Namespace function names start with an lowercase (and then follow Camel Case)

void func();

In multi-word namespace function names, each word starts with an upper case, except for the first word.

void thisFunctionDoesSomething();
Variables

Variable names start with a lower case character.

float x;

In multi-word variable names the first word starts with a lower case character and each successive word starts with an upper case.

float maxDistanceFromPlane;

Public struct variables are pascal cased. Classes should not have any public variables, but rather friends and Get/Set functions should be used. You should avoid making variables public, instead consider making accessor and mutator functions. The time when they would be public is if the struct you are writing is a datatype that is composed of other datatypes (as with Vector2 which has X and Y, or Color which has R, G, B, and A), other variables that are not fundamentally part of the type should be private or protected.

double X;
double Direction;
Structs and Classes

Struct and class names should be pascal cased.

struct RenderEntity;

Typedef’d types use the same naming convention.

typedef FileHandle int;

Unless they are defining another primitive data type

typedef byte unsigned char;
Enums

Enum names use the same naming convention as Classes. The enum constants should be in all capital, with underscores to designate separations between words.

enum Contact
{
	NONE,
	EDGE,
	MODEL_VERTEX,
	TRM_VERTEX
};

Const

Use:

const int* P;			// pointer to const int

Const variables, with a few exceptions, such as const char* should be all uppercase with underscores separating the words.

const long TIME_FROM_START = 100;
const char* inputText;

Classes

Function overloading should be avoided in most cases. For example, instead of:

	Foo*	Class::GetBar(int index);
	Foo*	Class::GetBar(const char* name);
	Foo*	Class::GetBar(float randomDiversity);

Use:

	Foo*	Class::GetBarByIndex(int index);
	Foo*	Class::GetBarByName(const char* name);
	Foo*	Class::GetRandomBar(float randomDiversity);

Explicitly named functions tend to be less prone to programmer error and inadvertent calls to functions due to wrong data types being passed in as arguments. Example:

Foo a = GetBar(0);

This could be meant as a call to get a random bar, but the compiler would interpret it as a call to get one by index.

Exceptions are when the number of arguments differs, but not the types

	Texture2D* Class::GenerateCircle(double radius);
	Texture2D* Class::GenerateCircle(double radius, Color color);
	Texture2D* Class::GenerateCircle(double radius, Color color, Color bgColor);

But if you’re doing that, you should be using default parameters anyway

	Texture2D* Class::GenerateCircle(double radius, Color color = Color::White, Color bgColor = Color::Black);

The only time you wouldn’t use default parameters is in a constructor where the parameters change their purpose

	Vector2(double X, double Y);
	Vector2(double magnitude, double direction, Heading heading);

File Names

Each class should be in a separate source file unless it makes sense to group several smaller classes. The file name should be the same as the name of the class.

class Winding;

files:

Winding.cpp, Winding.hpp

If the file contains no classes, it should be named something short and descriptive that fits the contents:

	MathHelper.hpp

Include #ifndef wrappers

The defines should be the filename, but all capital, with the . replaced by a _ and a _ on the end, as well as being prefixed by MINX_. Do NOT use #pragma once

#ifndef MINX_WINDING_HPP_
#define MINX_WINDING_HPP_
...
#endif

Instead of:

#pragma once

Comments

Single line comments should be used to explain code that is hard to understand or counter-intuitive. Multiline comments should be used for the license at the top of the file. Javadoc style comments should be used for documentation. All public and protected members of classes must be documented, private members should be documented. /* and */ should be on their own lines. The more descriptive the documentation the better.

Documentation comments should look like this:

/** Performs some function.
 * @param a The input of the function.
 * @return The result of the function.
 */
int SomeFunc(int a);
⚠️ **GitHub.com Fallback** ⚠️