Style Guides and Automatic Code Formatting
This lesson introduces the concept of Style Guides and ClangFormat, focusing on how to achieve consistency in our code
At this point, we're familiar with a lot of different techniques we can use when writing our programs. What's likely to be less familiar is when to apply those techniques.
When working for a company, or on a project shared by multiple developers, we strive to write code in a relatively consistent way. This is usually documented in something called a Style Guide.
Style Guides
Style guides are a developer's or company's opinion on how code should be written. They prescribe conventions like:
- What data types we should use? For example, should floating point numbers be
float
ordouble
? Should strings bestd::string
or something else? - How do we use language features - for example, in what scenarios should we use
auto
andconst
? - How do we name our variables, classes, and functions - for example, do we use
camelCase
,PascalCase
, orsnake_case
? Do we have some convention for class member variable names, such as prefixing them with anm
? - How do we use "white space" - that is, which code blocks are indented, and by how much? How wide can a line of code be before we should break it up across multiple lines?
Many developers and companies make these style guides public. We've referenced the Google C++ Style Guide and the Unreal Coding Standard a few times throughout this course.
Once we've agreed on a style guide, checking that our code conforms to it can be largely automated. In this lesson, we'll focus on automating the layout of our code, using white space.
In the next lesson, we'll focus on static analysis tools, that can automatically check that we're conforming to things like naming conventions, const
-correctness, header guards, and more.
White Space
We've already seen that the compiler doesn't necessarily care about how we use space in our code files. We can generally add additional space and line breaks as preferred.
From the compiler's point of view, all of the following are equivalent:
int Character::GetHealth() const
{
return Health;
}
int Character::GetHealth() const {
return Health;
}
int Character::
GetHealth() const
{ return Health; }
int
Character::GetHealth()
const {
return Health;
}
However, humans need to read our code too. We generally want to have code laid out consistently, so the overall structure of our files can be quickly understood at a glance.
Automatic Code Formatting
Experienced developers typically do not format their code manually. We automate this process.
Likely, you've already seen this in action - your editor has probably been indenting and laying out code for you.
Editors have settings that allow us to control that process, letting us specify how we want the formatting to work. In Visual Studio, for example, these settings are under Options > Text Editor > C/C++.
However, it's more common to create a configuration file that does this for us. Configuration files are easier to share across a team, and many formats work across different IDEs. This allows everyone to conform to the same style, without needing everyone to use the same editor, with the same settings.
A common choice for a format that works across a range of tools is ClangFormat.
ClangFormat
To use ClangFormat, we just need to create a file called .clang-format
(note the initial .
) in the root directory of our project.
In Visual Studio, we can create this by Right-Clicking on our project name in the Solution Explorer and selecting Add > New Item. In the Formatting section on the right, we should see the ClangFormat template. We should leave the name as the default (.clang-format
) and add it to our project.
Several style guides are available by default within clang-format. For example, we can use Google's style guide by adding a .clang-format
file with a single line of configuration:
BasedOnStyle: Google
Aside from Google, other style guides are available. You may want to try Mozilla
, LLVM
, and Microsoft
here instead.
From there, we can add additional rules to update or override our imported settings. For example, we could broadly use Microsoft's style, but set a different indent size and maximum line length using the following:
BasedOnStyle: Microsoft
IndentWidth: 2
ColumnLimit: 60
All the rules we can use to set up ClangFormat are available in the documentation.
Many .clang-format
files are available online for us to copy, update, and play around with until we find something that works for us.
Those interested in applying the style of Unreal Engine can use the .clang-format
file made available by TensorWorks (MIT License):
StatementMacros: [
'UPROPERTY', 'UFUNCTION', 'UCLASS', 'USTRUCT',
'UENUM', 'UINTERFACE', 'GENERATED_BODY'
]
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: Empty
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: false
ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true
Cpp11BracedListStyle: false
EmptyLineBeforeAccessModifier: LogicalBlock
IndentCaseBlocks: false
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 4
NamespaceIndentation: All
PointerAlignment: Left
SortIncludes: false
SpaceBeforeCaseColon: false
TabWidth: 4
UseTab: Always
Summary
In this lesson, we explored Style Guides, and how ClangFormat can automate code formatting. The key things we learned included:
- Understanding the role and contents of a Style Guide in coding, including decisions on data types, language features, naming conventions, and whitespace usage.
- The practice of maintaining consistent coding styles in collaborative environments and how style guides facilitate this.
- Introduction to ClangFormat as a tool for automating the layout of code, making adherence to chosen style guides quick and easy.
- Steps to create and customize a
.clang-format
file, with examples of incorporating popular style guides like Google's and Microsoft's. - Highlighting the practical application of ClangFormat in IDEs such as Visual Studio, and referencing online resources for further exploration.
Static Analysis
An introduction to static analysis tools, and how they can help beginners learn faster and improve code quality