4. 规则详解(1) 对齐(Align)
clang-format 中有很多 AlignXxx,可自行查看官网说明
1. 声明
AlignConsecutiveDeclarations,垂直对齐连续的声明。支持两种写法:简洁枚举形式、嵌套对象形式
# 写法一:枚举形式(快捷)
AlignConsecutiveDeclarations: None # 不对齐
AlignConsecutiveDeclarations: Consecutive # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveDeclarations: AcrossEmptyLines # 允许跨空行对齐
AlignConsecutiveDeclarations: AcrossComments # 允许跨注释对齐
AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments # 既跨空行又跨注释对齐
# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveDeclarations:
Enabled: true|false # 是否启用(等同于枚举中的 None / 非 None)
AcrossEmptyLines: true|false # 是否在遇到空行时继续对齐
AcrossComments: true|false # 是否在遇到注释时继续对齐
AlignFunctionDeclarations: true|false # 是否对函数声明(返回类型/名字)进行对齐
AlignFunctionPointers: true|false # 是否对函数指针声明(例如 int (*f)())进行对齐
- 未格式化
int a = 1;
int somelongname = 2;
/* a comment */
double c = 3;
unsigned int f1(void);
void f2(void);
size_t f3(void);
unsigned i;
int &r;
int *p;
int (*f)();
- 格式化(使能所有选项)
int a = 1;
int somelongname = 2;
/* a comment */
double c = 3;
unsigned int f1(void);
void f2(void);
size_t f3(void);
unsigned i;
int &r;
int *p;
int (*f)();
2. 赋值
AlignConsecutiveAssignments,对 “连续的赋值语句” 做列对齐(把=或赋值运算符对齐到同一列)
支持两种写法:简洁枚举形式、嵌套对象形式
# 写法一:枚举形式(快捷)
AlignConsecutiveAssignments: None # 不对齐
AlignConsecutiveAssignments: Consecutive # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveAssignments: AcrossEmptyLines # 允许跨空行对齐
AlignConsecutiveAssignments: AcrossComments # 允许跨注释对齐
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments # 既跨空行又跨注释对齐
# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveAssignments:
Enabled: true|false # 开启/关闭对齐
AcrossEmptyLines: true|false # 是否跨空行也继续对齐
AcrossComments: true|false # 是否跨注释行也对齐
AlignCompound: true|false # 是否包括复合赋值(+=, &=, >>= 等)
PadOperators: true|false # 是否左侧填充短赋值运算符以对齐(见示例)
- 未格式化
int main() {
int a = 1;
float somelongname = 2;
int x = 3;
int y = 4;
a &= 2;
somelongname = 2;
x >>= 2;
y = 2;
// 注释会中断对齐
int d = 4;
/* comment */
int e = 5;
}
- 格式化(使能所有选项,并且上一步的声明对齐都使能了)
int main() {
int a = 1;
float somelongname = 2;
int x = 3;
int y = 4;
a &= 2;
somelongname = 2;
x >>= 2;
y = 2;
// 注释不会中断对齐
int d = 4;
/* comment */
int e = 5;
}
3. 宏定义
AlignConsecutiveMacros,对连续的 #define 宏定义做列对齐
支持两种写法:简洁枚举形式、嵌套对象形式
# 写法一:枚举形式(快捷)
AlignConsecutiveMacros: None # 不对齐
AlignConsecutiveMacros: Consecutive # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveMacros: AcrossEmptyLines # 允许跨空行对齐
AlignConsecutiveMacros: AcrossComments # 允许跨注释对齐
AlignConsecutiveMacros: AcrossEmptyLinesAndComments # 既跨空行又跨注释对齐
# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveMacros:
Enabled: true|false # 开启/关闭对齐
AcrossEmptyLines: true|false # 是否跨空行也继续对齐
AcrossComments: true|false # 是否跨注释行也对齐
- 未格式化
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)
#define A 1
/* comment */
#define AFTER_COMMENT 100
#define ALONE 5
- 格式化(使能所有选项)
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)
#define A 1
/* comment */
#define AFTER_COMMENT 100
#define ALONE 5
4. 单行注释
AlignTrailingComments,尾随注释(行尾 // 或 /* ... */)的对齐方式
支持两种写法:传统方式、嵌套对象形式
# 写法一:传统方式(不推荐)
AlignTrailingComments: true|false # 开启/关闭对齐
# 写法二:嵌套对象形式(更灵活)
AlignTrailingComments:
# Leave:保持原样,不强制对齐(保留输入的注释位置)
# Always:始终对齐(把行末注释对齐到同一列)
# Never:不要对齐,但其它 formatter 仍可能调整注释
Kind: Leave | Always | Never
OverEmptyLines: <unsigned> # 在对齐时跨过多少个空行仍继续对齐(整数)
- 未格式化
int a = 1; // small
int abc = 2; // longer name
#define FOO 1 // macro comment
int x = 3; // trailing
// blank line breaks group
int y = 4; // next group
- 格式化(kind=Always OverEmptyLines=1 )
int a = 1; // small
int abc = 2; // longer name
#define FOO 1 // macro comment
int x = 3; // trailing
// blank line breaks group
int y = 4; // next group
5. 指针和引用
用来控制指针的 * 和引用的 &,如何对齐。
# Left:把 * / & 贴紧类型(例:int* a;)
# Right:把 * / & 贴近变量名(例:int *a;)
# Middle:将 * / & 独立为中间 token,两侧留空格(例:int * a;)
PointerAlignment: Left|Right|Middle
# true: clang-format 会扫描文件,依据文件里最常见的指针/引用对齐风格自动调整
# false: 使用 .clang-format 中明确指定的 PointerAlignment
DerivePointerAlignment: true|false
# 控制引用 & 的对齐方式;
# Pointer 表示按 PointerAlignment 的规则对齐引用
# Left/Right/Middle: 单独指定引用的表现
ReferenceAlignment: Pointer|Left|Right|Middle
# 控制在包含指针限定符(如 const)的情形是否在限定符前/后留空格。
# Default 表示不强制改变(以 PointerAlignment 规则为主)
# Before/After/Both: 可强制加空格,影响可读性样式,例如 void * const * x vs void *const *x
SpaceAroundPointerQualifiers: Default|Before|After|Both
- 效果一
// PointerAlignment=Right
// DerivePointerAlignment=false
// ReferenceAlignment=Pointer
// SpaceAroundPointerQualifiers=Default
int *a;
int *b;
int *c;
int *const p1;
int *const p2;
int &r1;
int &r2;
int &r3;
- 效果二
// PointerAlignment=Left
// DerivePointerAlignment=false
// ReferenceAlignment=Pointer
// SpaceAroundPointerQualifiers=Default
int* a;
int* b;
int* c;
int* const p1;
int* const p2;
int& r1;
int& r2;
int& r3;
6. AlignAfterOpenBracket
控制当括号/尖括号/方括号内的内容被折行时,后续行是否水平对齐到第一个元素
- 效果一
// AlignAfterOpenBracket: false
#include <tuple>
// 3) 尖括号(模板参数)演示
using MyTuple = std::tuple<int, long,
double, char>;
void someLongFunction (int a, int b, int c, int d) {}
int main () {
// 1) 圆括号(函数调用)演示
int arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4;
someLongFunction(arg1, arg2,
arg3, arg4);
// 2) 方括号(索引表达式)演示
int arr[] = {1, 2,
3, 4, 5};
MyTuple t{1, 2, 3.0, 'a'};
return 0;
}
- 效果二
// AlignAfterOpenBracket: true
#include <tuple>
// 3) 尖括号(模板参数)演示
using MyTuple = std::tuple<int, long,
double, char>;
void someLongFunction (int a, int b, int c, int d) {}
int main () {
// 1) 圆括号(函数调用)演示
int arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4;
someLongFunction(arg1, arg2,
arg3, arg4); // 格式化时 AlignAfterOpenBracket 决定第二行起始列
// 2) 方括号(索引表达式)演示
int arr[] = {1, 2,
3, 4, 5};
MyTuple t{1, 2, 3.0, 'a'};
return 0;
}
7. AlignConsecutiveShortCaseStatements
垂直对齐连续的声明。支持两种写法:简洁枚举形式、嵌套对象形式
AlignConsecutiveShortCaseStatements:
Enabled: true|false # 是否启用对齐行为(true/false)
AcrossEmptyLines: true|false # 是否跨空行对齐(true:跨空行也对齐;false:空行会中断对齐块)
AcrossComments: true|false # 是否跨注释行对齐(true:注释不会中断对齐;false:注释中断对齐)
AlignCaseColons: true|false # 控制对齐是以 : 为对齐锚点,还是以 : 后的 token 对齐
- 效果一
// AlignConsecutiveShortCaseStatements:
// Enabled: false
// AcrossEmptyLines: true
// AcrossComments: true
// AlignCaseColons: true
#include <iostream>
#include <string>
const char* level_name (int level) {
switch ( level ) {
case 1: return "debug";
case 10: return "info";
case 100: return "warning";
// more levels could be here
default: return "unknown";
}
}
int main () {
std::cout << level_name(100) << std::endl;
return 0;
}
- 效果二
// AlignConsecutiveShortCaseStatements:
// Enabled: true
// AcrossEmptyLines: true
// AcrossComments: true
// AlignCaseColons: true
#include <iostream>
#include <string>
const char* level_name (int level) {
switch ( level ) {
case 1 : return "debug";
case 10 : return "info";
case 100: return "warning";
// more levels could be here
default : return "unknown";
}
}
int main () {
std::cout << level_name(100) << std::endl;
return 0;
}
- 效果三
// AlignConsecutiveShortCaseStatements:
// Enabled: true
// AcrossEmptyLines: true
// AcrossComments: true
// AlignCaseColons: false
#include <iostream>
#include <string>
const char* level_name (int level) {
switch ( level ) {
case 1: return "debug";
case 10: return "info";
case 100: return "warning";
// more levels could be here
default: return "unknown";
}
}
int main () {
std::cout << level_name(100) << std::endl;
return 0;
}
本文是博主原创文章,转载请注明来源 明王讲QT







