Introduction
C and C++ code formatting can significantly improve readability and maintainability of your projects. This comprehensive reference guide covers two of the most popular C/C++ code formatters: clang-format and AStyle (Artistic Style).
Both tools provide robust formatting capabilities but differ in their approach, configuration options, and integration methods. This guide will help you understand how to use each tool effectively.
clang-format Documentation
clang-format is part of the LLVM toolchain and provides powerful, customizable formatting for C, C++, Objective-C, and other languages. It's widely regarded as the industry standard for C/C++ formatting.
Installation
clang-format can be installed through several methods:
Package Managers:
# Ubuntu/Debian
sudo apt-get install clang-format
# macOS
brew install clang-format
# Windows (with Chocolatey)
choco install llvm
# Windows (with Scoop)
scoop install llvm
From Source:
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build && cd build
cmake -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" ../llvm
make clang-format
Command-line Usage
Basic usage of clang-format:
# Format a file in-place
clang-format -i file.cpp
# Format with a specific style
clang-format -style=llvm -i file.cpp
# Format with a custom configuration file
clang-format -style=file -i file.cpp
# Format a specific range of lines
clang-format -lines=10:20 -i file.cpp
# Dump the configuration for a specific style
clang-format -style=llvm -dump-config > .clang-format
# Format multiple files
find . -name "*.cpp" -o -name "*.h" | xargs clang-format -i
Configuration Options
clang-format uses a YAML configuration file, typically named{" "}
.clang-format
, placed in your project root or in parent
directories.
Example configuration file:
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^'
Priority: 2
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ''
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never
Style Options
clang-format comes with several predefined styles:
- LLVM: The default style used by LLVM projects
- Google: Google's C++ style guide
- Chromium: The Chromium project's style guide
- Mozilla: The Mozilla project's style guide
- WebKit: The WebKit project's style guide
- Microsoft: Microsoft's C++ style
- GNU: GNU coding standards
You can base your custom style on any of these:
---
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 100
# Override other options as needed
AStyle Documentation
Artistic Style (AStyle) is a free, open-source formatter for C, C++, C#, and Java. It offers a different approach to formatting compared to clang-format, with its own set of features.
Installation
Package Managers:
# Ubuntu/Debian
sudo apt-get install astyle
# macOS
brew install astyle
# Windows (with Chocolatey)
choco install astyle
# Windows (with Scoop)
scoop install astyle
From Source:
git clone https://gitlab.com/saalen/astyle.git
cd astyle/build
cmake ../
make
sudo make install
Command-line Options
Basic usage of AStyle:
# Format a file in-place
astyle file.cpp
# Format with a specific style
astyle --style=allman file.cpp
# Format using a configuration file
astyle --options=astylerc file.cpp
# Format recursively
astyle --recursive *.cpp *.h
# Format with specific indentation
astyle --indent=spaces=4 file.cpp
# Create a backup before formatting
astyle --suffix=.orig file.cpp
# Format without creating backups
astyle --suffix=none file.cpp
Configuration File
AStyle can use a configuration file (often named astylerc
)
that contains command-line options, one per line.
Example configuration file:
# AStyle Configuration
--style=google
--indent=spaces=4
--indent-classes
--indent-switches
--indent-cases
--indent-namespaces
--indent-labels
--indent-preprocessor
--max-instatement-indent=40
--min-conditional-indent=0
--break-blocks
--pad-oper
--pad-header
--unpad-paren
--add-brackets
--convert-tabs
--align-pointer=name
--align-reference=name
--break-closing-brackets
--max-code-length=100
--break-after-logical
--suffix=none
--lineend=linux
Style Options
AStyle offers several predefined formatting styles:
- allman: Allman style (ANSI), with broken brackets
- java: Java style, with attached brackets
- kr: Kernighan & Ritchie style, with broken brackets for classes
- stroustrup: Stroustrup style, similar to K&R
- whitesmith: Whitesmith style, with broken, indented brackets
- vtk: VTK style, similar to Allman but with indented switch blocks
- ratliff: Ratliff style, similar to Java but with closing brackets at the original indent
- gnu: GNU style, with broken brackets and extra indentation
- linux: Linux style, with broken brackets and indented case statements
- horstmann: Horstmann style, with run-in brackets
- 1tbs: "One True Brace Style"
- google: Google style, similar to K&R but with broken brackets for function declarations
- mozilla: Mozilla style, similar to K&R but with slightly different bracket placement
- webkit: WebKit style
- pico: Pico style, with all brackets and block indents minimized
- lisp: Lisp style, with closing brackets aligned with the opening line
Comparison
Here's a comparison between clang-format and AStyle:
Feature | clang-format | AStyle |
---|---|---|
Configuration Format | YAML | Plain text (options per line) |
Integration with Build Tools | Excellent (part of LLVM) | Good |
IDE Support | Excellent (VS Code, CLion, Visual Studio, etc.) | Good |
Formatting Granularity | Very fine-grained control | Moderate control |
Language Support | C, C++, Objective-C, Java, JavaScript, JSON, etc. | C, C++, C#, Java |
Performance | Fast | Very fast |
Development Activity | Very active | Moderate |
IDE Integration
Both formatters integrate well with popular IDEs:
clang-format
- Visual Studio: Built-in support in recent versions, or via the "Clang Power Tools" extension
- VS Code: Via the "C/C++" extension from Microsoft
- CLion: Built-in support
- Vim: Via plugins or direct command invocation
- Emacs: Via the clang-format.el script
AStyle
- Visual Studio: Via extensions like "AStyle Format"
- VS Code: Via extensions like "AStyle"
- Eclipse: Via CDT
- Vim: Via plugins
- Emacs: Via astyle-mode
Troubleshooting
Common issues and their solutions:
clang-format
- Configuration Not Applied: Ensure your .clang-format file is in the project root or a parent directory
- Unexpected Formatting: Check for style configuration mismatches or validate your YAML syntax
- Version Differences: clang-format can change between versions; specify version in CI pipelines
AStyle
- Options Not Applied: Verify your options file syntax and path
- Backup Files Accumulation: Use --suffix=none to prevent backup creation
- Unwanted Changes: AStyle might be aggressive with some formatting; refine your options
Conclusion
Both clang-format and AStyle are excellent C/C++ code formatters with their own strengths. clang-format provides more fine-grained control and is part of the LLVM ecosystem, making it ideal for larger projects or those already using LLVM tools. AStyle is simpler to configure and faster for basic formatting needs.
For most modern C++ projects, especially those following standard style guides like Google's or LLVM's, clang-format is usually the recommended choice. However, AStyle remains a solid alternative, particularly for projects with simpler formatting requirements or those targeting multiple languages like C# and Java alongside C++.
The best approach is to choose one formatter, establish a clear style guide for your project, and ensure consistent usage across your team through integration with your development workflow and CI/CD pipeline.