Rules
Naming#
Use lowerCamelCase for variables and functions.
int userAge {};
int maxAttempts {};
int totalScore {};
int readNumber();
int calculateTotal();
void printResult(int value);
Variables should usually be nouns.
int number {};
int result {};
int attempts {};
std::string name {};
Functions should usually start with verbs.
readNumber()
calculateScore()
printResult()
isEven()
hasInput()
Names should explain intent.
// Bad
int data {};
int thing {};
int temp {};
// Better
int userAge {};
int finalScore {};
int selectedOption {};
Use short generic names only in tiny scopes.
for (int i { 0 }; i < 10; ++i)
{
}
Use descriptive names when the variable lives longer than a few lines.
for (int studentIndex { 0 }; studentIndex < studentCount; ++studentIndex)
{
}
Boolean names should read like yes/no questions.
bool isValid {};
bool hasInput {};
bool shouldPrint {};
bool canMove {};
Avoid negative boolean names when possible.
// Harder to read
bool isNotValid {};
bool hasNoInput {};
File names should be lowercase with underscores.
main.cpp
io.cpp
math.cpp
user_input.cpp
score_calculator.cpp
game_state.cpp
Use one word for a simple concept.
main.cpp
io.cpp
math.cpp
Use underscores for descriptive names with multiple words.
user_input.cpp
score_calculator.cpp
game_state.cpp
Name files after what they contain or the responsibility they handle.
user_input.cpp reading input from the user
score_calculator.cpp score calculation logic
game_state.cpp game state data and helpers
Avoid vague file names.
utils.cpp
helpers.cpp
stuff.cpp
Functions#
One function should do one job.
- read input
- calculate result
- print output
Keep main() simple.
int main()
{
int number { readNumber() };
int result { doubleNumber(number) };
printResult(result);
return 0;
}
Use parameter names that explain the role.
int doubleNumber(int number);
int calculateArea(int width, int height);
Avoid meaningless parameter names.
// Bad
int calculateRectangleArea(int x, int y);
// Good
int calculateRectangleArea(int width, int height);
// Fine for coordinates
int calculateDistance(int x1, int y1, int x2, int y2);
If a function returns a value, use the returned value.
int number { readNumber() };
Do not call a function and expect an argument to change unless it was designed to do that.
// Bad
readNumber(number);
Function names should make side effects obvious.
int calculateResult(int number);
void printResult(int result);
int readNumber();
Avoid hidden side effects inside calculation functions.
// Bad
int calculateResult(int number)
{
std::cout << "Calculating...\n";
return number * 2;
}
Variables#
Use brace initialization by default.
int number {};
int maxAttempts { 3 };
std::string name {};
Declare variables close to where they are used.
int number { readNumber() };
int result { doubleNumber(number) };
printResult(result);
Do not create variables before they are needed.
// Bad
int number {};
int result {};
// many lines later...
Use const when a value should not change.
const int maxAttempts { 3 };
Use constexpr for true compile-time constants.
constexpr int maxAttempts { 3 };
Use named constants instead of unexplained numbers.
constexpr int maxAttempts { 3 };
if (attempts >= maxAttempts)
{
return;
}
Comments#
Do not comment what the code already says.
// Bad
// add 1 to count
++count;
Comment why something exists.
// User gets three attempts before program exits.
constexpr int maxAttempts { 3 };
Do not use comments to excuse bad names.
// Bad
int d {}; // user age
// Better
int userAge {};
Files#
Do not include .cpp files.
// Bad
#include "io.cpp"
// Good
#include "io.h"
Include only what the file uses.
#include "io.h"
#include <iostream>