C++ 代码格式化方案配置 / Configuring C++ code format

Date:

Author:


为了在多人协同下保持 C++ 代码格式(特别是缩进)的统一,避免代码库提交历史中频繁出现无谓的格式变化而使有意义的修改难以追溯,在此给出在 IDE/代码编辑器中保持代码格式一致性的一种配置方案。

In order to maintain the consistency of C++ code format (esp. the indentation) during collaboration, and prevent the frequent meaningless format changes in a repository’s commit history, which may hinder the tracing (blaming) of the actual code changes, this post gives possible configuration for keeping the code format consistency among several IDEs/editors.

1. 动机

不同 IDE/代码编辑器的默认配置中对缩进的处理不同:Qt Creator 中默认仅使用 Space,且在保存时自动检查是否有 Tab 并转换为 Space;Visual Studio 中默认仅使用 Tab,在保存时不作额外的转换;Visual Studio Code 自动匹配所编辑文件中已有的缩进形式。在多编辑器混用的环境下,代码提交历史上常出现 Tab 转 Space、Space 转 Tab 的情况,不利于代码修改的追溯。

注:以下以 Visual Studio 默认格式(仅常用配置项)为基准给出在其他 IDE/代码编辑器中的配置实例,不同代码格式的配置需另行调整。

2. 格式化工具

ClangFormat 是 LLVM/Clang 附带的代码格式化工具,安装 LLVM(安装后占用 2 GB 磁盘空间)即可获得,也可单独提取 clang-format.exe(约 5 MB)以节省空间。以下使用 ClangFormat 给出 Windows 环境下几种 IDE/代码编辑器中的配置和使用方法,所用配置以 ClangFormat 内置的 LLVM 规范为基础,通过少量调整以匹配 Visual Studio 的默认格式。

扩展阅读:Clang-Format Style Options — Clang documentation

3. Visual Studio

3.1. 配置

配置项位于「Tools → Options… → Text Editor → C/C++ → Formatting」,Visual Studio 2017/2019/2022 中「General → Default formatting style」项的默认配置已经是「Visual Studio」。VS 2015 无内置代码格式供选择,也无法使用 ClangFormat,需在窗口中逐项调整,在此不作修改。

参考资料:Set C++ coding style and formatting | Microsoft Docs

3.2. 使用

通过「Edit → Advanced → Format Document」(Ctrl+K, Ctrl+D)格式化当前文档,或「Edit → Advanced → Format Selection」(Ctrl+K, Ctrl+F)格式化所选区域。一般应仅对自己所修改区域执行格式化,而不要变动其他代码。

4. Qt Creator

4.1. 配置

选择「Help → About Plugins…」,在 Installed Plugins 窗口中勾选「C++ → Beautifier (experimental)」或「C++ → ClangFormat」,关闭窗口并重启 Qt Creator。

配置、使用 ClangFormat 插件的方法不再列出。Beautifier 可选择多种格式化工具,以下通过 Beautifier 调用 ClangFormat。

在「Tools → Options… → Beautifier → Clang Format」的 Options 组框中选择「Use customized style」并添加新的配置,「Name」栏中可填入「Visual Studio」,「Value」文本框中填入以下内容(YAML 格式)。

{
  BasedOnStyle: LLVM,
  UseTab: ForContinuationAndIndentation,
  IndentWidth: 4,
  TabWidth: 4,
  BreakBeforeBraces: Allman,
  IndentCaseLabels: false,
  ColumnLimit: 0,
  AccessModifierOffset: -4,
  NamespaceIndentation: All,
}

在「General」选项卡中可设置在保存文件时自动执行格式化,但建议仅对自己所关注的代码段执行格式化操作(见下方「4.2. 使用」)。

在选项窗口中点击「Apply」或「OK」后才会保存上述配置。(对 Beautifier 的配置保存在 <User>\AppData\Roaming\QtProject\QtCreator.ini,自定义的代码格式位于 <User>\AppData\Roaming\QtProject\beautifier\clangformat\<FormatName>\.clang-format。)

上述配置仅在手动调用或保存文件时执行,不影响在 Qt Creator 中编辑文件时的行为。因此建议在选项窗口中再修改「C++ → Code Style」,导入如下所示的 XML 文档并应用,以使编辑时使用的代码格式与之尽量一致。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorCodeStyle>
<qtcreator>
 <data>
  <variable>CodeStyleData</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="AlignAssignments">false</value>
   <value type="bool" key="AutoSpacesForTabs">true</value>
   <value type="bool" key="BindStarToIdentifier">true</value>
   <value type="bool" key="BindStarToLeftSpecifier">false</value>
   <value type="bool" key="BindStarToRightSpecifier">false</value>
   <value type="bool" key="BindStarToTypeName">false</value>
   <value type="bool" key="ExtraPaddingForConditionsIfConfusingAlign">true</value>
   <value type="bool" key="IndentAccessSpecifiers">false</value>
   <value type="bool" key="IndentBlockBody">true</value>
   <value type="bool" key="IndentBlockBraces">false</value>
   <value type="bool" key="IndentBlocksRelativeToSwitchLabels">false</value>
   <value type="bool" key="IndentClassBraces">false</value>
   <value type="bool" key="IndentControlFlowRelativeToSwitchLabels">false</value>
   <value type="bool" key="IndentDeclarationsRelativeToAccessSpecifiers">true</value>
   <value type="bool" key="IndentEnumBraces">false</value>
   <value type="bool" key="IndentFunctionBody">true</value>
   <value type="bool" key="IndentFunctionBraces">false</value>
   <value type="bool" key="IndentNamespaceBody">true</value>
   <value type="bool" key="IndentNamespaceBraces">false</value>
   <value type="int" key="IndentSize">4</value>
   <value type="bool" key="IndentStatementsRelativeToSwitchLabels">true</value>
   <value type="bool" key="IndentSwitchLabels">false</value>
   <value type="int" key="PaddingMode">2</value>
   <value type="bool" key="ShortGetterName">true</value>
   <value type="bool" key="SpacesForTabs">true</value>
   <value type="int" key="TabSize">4</value>
  </valuemap>
 </data>
 <data>
  <variable>DisplayName</variable>
  <value type="QString">Visual Studio</value>
 </data>
</qtcreator>

4.2. 使用

为手动调用代码格式化,需在「Tools → Options… → Environment → Keyboard」中设置快捷键,定位到 ClangFormat 组并设置所需的项。

5. Visual Studio Code

5.1. 配置

插件「C/C++」(ms-vscode.cpptools)可调用自带的 clang-format.exe,相关的默认配置(JSON 格式)如下,不需调整。可在 Command Pallete… 中打开「Preferences: Open User Settings」,搜索、查看这些配置。

{
	"Clang_format_style": "file",
	"Clang_format_fallback": "Visual Studio"
}

也可使用插件「Clang-Format」(xaver.clang-format),配置和使用方法略。

5.2. 使用

仅可使用 Alt+Shift+F 格式化当前文件,无法针对部分区域执行格式化。


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.