Clang-format格式化C代碼
官方參考文檔:
-
Clang-Format Style Options — Clang 16.0.0git documentation (llvm.org)
-
ClangFormat — Clang 16.0.0git documentation (llvm.org)
1.引言&安裝
1.1引言
進(jìn)入公司之后,會(huì)發(fā)現(xiàn)每個(gè)公司都有自己的代碼規(guī)范,針對(duì)于其中的代碼格式規(guī)范,手動(dòng)去控制十分繁瑣,因此這里提供一種通過配置相關(guān)規(guī)則使用腳本進(jìn)行格式控制的方法。
Clang-format是一種代碼格式化工具,可以用來格式化各種代碼,可以支持以下語言:
?
C/C++/Java/JavaScript/Objective-C/Protobuf/C#
此外,也可以使用prettier
,但是其對(duì)c語言支持有限。
使用方法如下:
?
USAGE: clang-format [options] [<file> ...]
更多的信息可以查找使用幫助。正常來說,使用以下命令就夠了:
?
clang-format -style=可選格式名 [-i] main.c
上面即可根據(jù)指定的格式對(duì)指定的文件進(jìn)行格式化 ,默認(rèn)的格式有以下種類:
-
LLVM
A style complying with the LLVM coding standards -
Google
A style complying with Google’s C++ style guide -
Chromium
A style complying with Chromium’s style guide -
Mozilla
A style complying with Mozilla’s style guide -
WebKit
A style complying with WebKit’s style guide -
Microsoft
A style complying with Microsoft’s style guide -
GNU
A style complying with the GNU coding standards
此外還可以指定為InheritParentConfig
,表示繼承上一級(jí)父文件夾內(nèi)的.clang- format
配置,甚至可以指定繼承其中的一部分:--style={BaseOnStyle:InheritParentConfig, ColumnLimit:20}
。
此外可以指定風(fēng)格為-style=file
,表示使用自定義的配置文件。
Clang-format的配置文件可以取名為.clang-format
或者_clang- format
。該文件可以放在根目錄或者最近的父目錄,Clang-format都會(huì)自己去嘗試尋找配置文件。
也可以直接指定配置文件的完整路徑 :-style=file:<format_file_path>
。
下面命令導(dǎo)出配置文件,以此為基礎(chǔ)進(jìn)行自定義(.clang-foramt)
?
clang-format -style=可選格式名 -dump-config > .clang-format
.clang-format
配置文件使用YAML
格式,如下:
?
key1: value1
key2: value2
#A comment
...
- YAML 入門教程 | 菜鳥教程 (runoob.com)
可以在配置文件時(shí),一次性使用多個(gè)語言配置:
?
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 4
---
Language: Cpp
# Force pointers to the type for C++.
DerivePointerAlignment: false
PointerAlignment: Left
---
Language: JavaScript
# Use 100 columns for JS.
ColumnLimit: 100
---
Language: Proto
# Don't format .proto files.
DisableFormat: true
---
Language: CSharp
# Use 100 columns for C#.
ColumnLimit: 100
...
也可以在源碼里面進(jìn)行特殊注釋,來表明哪一段代碼不需要格式化 。
?
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
// clang-format off
和// clang-format on
自身會(huì)被格式化。
1.2 安裝
Windows:
直接使用vscode安裝相關(guān)插件(例如Clang-Format)即可。
可以使用已經(jīng)定義到的一些規(guī)則,也可以自定義規(guī)則。
Linux:
sudo apt install clang-format
注意,該版本同樣大概率不是最新的,因此一些特性是無法使用的 。
2. 配置字解釋
2.1 language 編程語言
?
# 語言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
可以指定當(dāng)前配置文件為了哪些文件配置的。
2.2 BaseOnStyle 基礎(chǔ)風(fēng)格
?
BasedOnStyle: LLVM|Google|Chromium|Mozilla|WebKit|Microsoft|GNU
指定基本的風(fēng)格樣式,實(shí)際開發(fā)時(shí)無需從頭開始指定所有的格式。
2.3 AccessModifierOffset 訪問性修飾符偏移
?
# 訪問說明符(public、private等)的偏移(縮進(jìn)或者對(duì)齊)
AccessModifierOffset: -4
這個(gè)是相對(duì)于原來已有的縮進(jìn)而言:
?
template <typename type> //模板定義
// template <class type> 較老的實(shí)現(xiàn)
class stack //定義一個(gè)模板類
{
private: //私有是默認(rèn)屬性,可省略
//類聲明中無法給沒有分配空間的變量賦值(只是一起聲明了一類變量)
//某些常量或者靜態(tài)常量變量(含有存儲(chǔ)空間)則可以初始化
int var;
}
原來的縮進(jìn)是4個(gè)空白字符,這個(gè)表明在原來縮進(jìn)4個(gè)字符的情況下偏移量,即回退4個(gè)字符,那相當(dāng)于不縮進(jìn)了。
2.4 AlignAfterOpenBracket 開括號(hào)后的對(duì)齊
?
# 開括號(hào)(開圓括號(hào)、開尖括號(hào)、開方括號(hào))后的對(duì)齊: Align, DontAlign, AlwaysBreak(總是在開括號(hào)后換行)
AlignAfterOpenBracket: Align
-
Align
,在開括號(hào)之后對(duì)齊變量someLongFunction(argument1,
argument2); -
DontAlign
, 不對(duì)齊,換行后使用ContinuationIndentWidth
。someLongFunction(argument1,
argument2); -
AlwaysBreak
,一行放不下時(shí),總是在一個(gè)開括號(hào)之后換行。someLongFunction(
argument1, argument2); -
BlockIndext
,一行放不下時(shí),總是在一個(gè)開括號(hào)之后換行,且在新行關(guān)閉尾括號(hào)。 僅限于圓括號(hào) 。someLongFunction(
argument1, argument2
)
2.5 AlignArrayOfStructures 對(duì)齊結(jié)構(gòu)體數(shù)組
當(dāng)數(shù)組的列數(shù)相等時(shí),會(huì)對(duì)齊每行的文本。
-
Left
,左對(duì)齊列:struct test demo[] =
{
{56, 23, “hello”},
{-1, 93463, “world”},
{7, 5, “!!” }
}; -
Right
,右對(duì)齊列:struct test demo[] =
{
{56, 23, “hello”},
{-1, 93463, “world”},
{ 7, 5, “!!”}
};
使用None
表示不用對(duì)齊。
2.6 AlignConsecutiveAssignments 對(duì)齊連續(xù)賦值
?
# 連續(xù)賦值時(shí),對(duì)齊所有等號(hào)
AlignConsecutiveAssignments: true
下面的格式是連續(xù)賦值:
?
int a = 1;
int somelongname = 2;
double c = 3;
該選項(xiàng)有兩種生效方法, 低版本只支持指定固定的模式 ,如下面其中一種:
?
#配置一個(gè)參數(shù):None - Consecutive - AcrossEmptyLines - AcrossComments - AcrossEmptyLinesAndComments
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
最新版本支持分別指定屬性,包括額外對(duì)混合元素符(+=等)的支持:
?
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCompound: true
PadOperators: true
-
bool Enabled: true
默認(rèn)的連續(xù)賦值對(duì)齊在以下的情況下生效:int a = 1;
int somelongname = 2;
double c = 3;int aaaa : 1;
int b : 12;
int ccc : 8;int aaaa = 12;
float b = 23;
std::string ccc; -
bool AcrossEmptyLines
可以跨越空白行進(jìn)行對(duì)齊true:
int a = 1;
int somelongname = 2;
double c = 3;int d = 3;
false:
int a = 1;
int somelongname = 2;
double c = 3;int d = 3;
-
bool AcrossComments
可以跨越注釋行進(jìn)行對(duì)齊true:
int d = 3;
/* A comment. */
double e = 4;false:
int d = 3;
/* A comment. */
double e = 4; -
bool AlignCompound
混合運(yùn)算符+=
會(huì)對(duì)齊于=
(僅限于連續(xù)賦值)true:
a &= 2;
bbb = 2;false:
a &= 2;
bbb = 2; -
bool PadOperators
混合運(yùn)算符填補(bǔ)對(duì)齊到所有左值的最右邊邊界。(僅限于連續(xù)賦值)true:
a >>= 2;
bbb = 2;a = 2;
bbb >>= 2;false:
a >>= 2;
bbb = 2;a = 2;
bbb >>= 2;
2.7 AlignConsecutiveBitFields 位段對(duì)齊
主要用于結(jié)構(gòu)體位段的對(duì)齊,如下:
?
struct aa {
int test : 4;
int b : 5;
int c : 8;
};
其支持以下屬性:
?
None - Consecutive - AcrossEmptyLines - AcrossComments - AcrossEmptyLinesAndComments
其設(shè)置方法和屬性與AlignConsecutiveAssignments
一致。
?
AlignConsecutiveBitFields: AcrossEmptyLinesAndComments
#或者
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
2.8 AlignConsecutiveDeclarations 連續(xù)聲明對(duì)齊
可以對(duì)齊變量等連續(xù)聲明的語句。
?
int aaaa = 12;
float b = 23;
std::string ccc;
const char hexdigits[] = "0123456789abcdef";
void Ipv6_deal(const uint16_t *a);
int main(const uint16_t *a, const uint16_t *k) { ... }
需要注意,這個(gè)方法配置最好不要跨過空白行,因?yàn)槿菀装押瘮?shù)定義也給對(duì)齊了 。
其支持以下屬性:
?
None - Consecutive - AcrossEmptyLines - AcrossComments - AcrossEmptyLinesAndComments
其設(shè)置方法和屬性與AlignConsecutiveAssignments
一致。
?
AlignConsecutiveDeclarations: AcrossComments
#或者
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
2.9 AlignConsecutiveMacros 連續(xù)宏定義對(duì)齊
?
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)
需要注意,這個(gè)方法配置最好不要跨過空白行,因?yàn)榭瞻仔锌梢杂脕碜龆畏指罘?/strong> 。
其支持以下屬性:
?
None - Consecutive - AcrossEmptyLines - AcrossComments - AcrossEmptyLinesAndComments
其設(shè)置方法和屬性與AlignConsecutiveAssignments
一致。
?
AlignConsecutiveMacros: AcrossComments
#或者
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
2.10 AlignEscapedNewlines 對(duì)齊分割語法行的斜杠符\
有三個(gè)選項(xiàng):DontAlign
、Left
、Right
左對(duì)齊,是盡可能的向左邊對(duì)齊。
?
true:
#define A \
int aaaa; \
int b; \
int dddddddddd;
右對(duì)齊是對(duì)齊到列的最右邊:
?
#define A \
int aaaa; \
int b; \
int dddddddddd;
2.11 AlignOperands 豎直對(duì)齊表達(dá)式的操作數(shù)
豎直對(duì)齊二元表達(dá)式或者三元表達(dá)式操作數(shù)。
可用選項(xiàng)有:DontAlign
,Align
,AlignAfterOperators
對(duì)齊操作符是在需要換行時(shí)來起作用的,如下:
?
int aaa = bbbbbbbbbbbbbbb +
ccccccccccccccc;
如果指定BreakBeforeBinaryOperators
,那么操作符+
也會(huì)被換行。
?
int aaa = bbbbbbbbbbbbbbb
+ ccccccccccccccc;
AlignAfterOperators
選項(xiàng)是當(dāng)BreakBeforeBinaryOperators
被設(shè)置時(shí),會(huì)將操作符對(duì)齊:
?
int aaa = bbbbbbbbbbbbbbb
+ ccccccccccccccc;
2.12 AlignTrailingComments 對(duì)齊尾部注釋
舊版本是bool值,直接使用true或者false。( 16版本才執(zhí)行下面的語法 )
True等價(jià)于,Always + OverEmptyLines: 0 。
?
AlignTrailingComments:
Kind: Always
OverEmptyLines: 1
Kind
的值可以選擇為:Leave
,Always
,Never
。
leave
保留不做格式化:
?
int a; // comment
int ab; // comment
int abc; // comment
int abcd; // comment
Always
對(duì)齊尾部注釋:
?
int a; // comment
int ab; // comment
int abc; // comment
int abcd; // comment
Never
不對(duì)齊尾部注釋,但是應(yīng)用其他的格式化手段,如縮進(jìn)。
?
int a; // comment
int ab; // comment
int abc; // comment
int abcd; // comment
OverEmptyLines
是跨越的空白行數(shù),超過這個(gè)行數(shù)的注釋不會(huì)對(duì)齊(分別對(duì)齊自身所屬段)。
?
int a; // these are
int ab; // aligned
?
int abcdef; // but this isn't
2.13 AllowAllArgumentsOnNextLine 允許參數(shù)在下一行上
如果函數(shù)調(diào)用或帶括號(hào)的初始化列表不在一行中,則允許將所有參數(shù)放到下一行,即使BinPackArguments
為false
。
?
AllowAllArgumentsOnNextLine: true
?
?
true:
callFunction(
a, b, c, d);
false:
callFunction(a,
b,
c,
d);
2.14 AllowAllConstructorInitializersOnNextLine 已棄用
See NextLine
of PackConstructorInitializers
.
2.15 AllowAllParametersOfDeclarationOnNextLine 允許聲明的參數(shù)在下一行上
函數(shù)聲明的參數(shù)無法放在一行上,允許將所有的變量放在下一行上,盡管BinPackParameters
isfalse
。
?
true:
void myFunction(
int a, int b, int c, int d, int e);
false:
void myFunction(int a,
int b,
int c,
int d,
int e);
2.16 AllowShortBlocksOnASingleLine 允許短語法塊在單行上
根據(jù)情況,while (true) { continue;}
可以放在單行上。
可以是以下值:Never
,Empty
,Always
。
Never
從不合并塊到單行上。
?
while (true) {
}
while (true) {
continue;
}
Empty
只合并空塊到單行上。
?
while (true) {}
while (true) {
continue;
}
Always
總是合并短塊到單行上。
?
while (true) {}
while (true) { continue; }
2.17 AllowShortEnumsOnASingleLine 允許短枚舉在單行上
?
true:
enum { A, B } myEnum;
false:
enum {
A,
B
} myEnum;
2.18 AllowShortFunctionsOnASingleLine 允許短函數(shù)在單行上
根據(jù)情況,int f() { return 0;}
可以被放在單行上。
可以選擇以下值:None
,InlineOnly
,Empty
,Inline
,ALL
。
None
從不合并函數(shù)到單行。
InlineOnly
僅合并被定義在類里面的短函數(shù),與Inline
區(qū)別在于不含外部頂級(jí)定義的空函數(shù)。
?
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
Empty
只合并空函數(shù)。
?
void f() {}
void f2() {
bar2();
}
Inline
合并被定義在類里面的短函數(shù),以及空函數(shù)。
?
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {}
All
合并所有合適的短函數(shù)在單行上。
?
class Foo {
void f() { foo(); }
};
void f() { bar(); }
2.19 AllowShortIfStatementsOnASingleLine 允許if塊在單行上
只對(duì)沒有括號(hào)的語句塊起作用,如if (a) return;
有以下的選項(xiàng):Never
,WithoutElse
,OnlyFirstIf
,AllIfsAndElse
Never
從不把if
塊放在單行上。
?
if (a)
return;
if (b)
return;
else
return;
if (c)
return;
else {
return;
}
WithoutElse
,僅在沒有else
語句時(shí)才會(huì)把if放在單行上。
?
if (a) return;
if (b)
return;
else
return;
if (c)
return;
else {
return;
}
OnlyFirstIf
只把第一個(gè)if語句放在單行,后續(xù)的else if
和else
都不會(huì)放在單行上。
?
if (a) return;
if (b) return;
else if (b)
return;
else
return;
if (c) return;
else {
return;
}
AllIfsAndElse
總是把短語句放在單行上。
?
if (a) return;
if (b) return;
else return;
if (c) return;
else {
return;
}
2.20 AllowShortLambdasOnASingleLine 允許短匿Lambda函數(shù)在單行上
只針對(duì)形式auto lambda []() {return 0;}
。
有以下選項(xiàng):None
,Empty
,Inline
,All
。
None
從不合并。
Empty
只合并空的Lambda函數(shù)。
?
auto lambda = [](int a) {};
auto lambda2 = [](int a) {
return a;
};
Inline
,當(dāng)Lambda函數(shù)作為變量時(shí),合并在單行上。
?
auto lambda = [](int a) {
return a;
};
sort(a.begin(), a.end(), []() { return x < y; });
All
合并所有適合的Lambda表達(dá)式在單行上。
?
auto lambda = [](int a) {};
auto lambda2 = [](int a) { return a; };
2.21 AllowShortLoopsOnASingleLine 允許合并短循環(huán)到單行上
當(dāng)配置為true
時(shí),形式while (true) continue
會(huì)被放在單行上。
2.22 AlwaysBreakAfterDefinitionReturnType 函數(shù)定義返回類型換行風(fēng)格
該選項(xiàng)已經(jīng)棄用.
-
None
,返回類型之后自動(dòng)斷行,PenaltyReturnTypeOnItsOwnLine
需要考慮在內(nèi)。 -
All
,總是在返回類型后斷行。 -
TopLevel
總是在頂級(jí)函數(shù)的返回類型處斷行。
2.23 AlwaysBreakAfterReturnType 函數(shù)聲明的返回類型換行風(fēng)格
有以下的選項(xiàng):None
,All
,TopLevel
,AllDefinitions
,TopLevelDefinitions
None
在返回類型之后自動(dòng)斷行, PenaltyReturnTypeOnItsOwnLine
需要考慮在內(nèi)。
?
class A {
int f() { return 0; };
};
int f();
int f() { return 1; }
All
總是在返回類型之后斷行.
?
class A {
int
f() {
return 0;
};
};
int
f();
int
f() {
return 1;
}
TopLevel
在頂級(jí)函數(shù)頂級(jí)返回類型處斷行。
?
class A {
int f() { return 0; };
};
int
f();
int
f() {
return 1;
}
AllDefinitions
在函數(shù)定義的返回類型處斷行。
?
class A {
int
f() {
return 0;
};
};
int f();
int
f() {
return 1;
}
TopLevelDefinitions
在頂級(jí)函數(shù)定義的返回類型處斷行。
?
class A {
int f() { return 0; };
};
int f();
int
f() {
return 1;
}
2.24 AlwaysBreakBeforeMultilineStrings 多行字符串?dāng)嘈?/h6>
在多行字符串字面量時(shí)之前斷行。
如下(只有當(dāng)字符串需要換行時(shí),才會(huì)生效):
?
true: false:
aaaa = vs. aaaa = "bbbb"
"bbbb" "cccc";
"cccc";
2.25 AlwaysBreakTemplateDeclarations 模板聲明斷行
有三個(gè)選項(xiàng):No
,MultiLine
,Yes
No
不會(huì)強(qiáng)制在模板聲明處斷行,需要考慮PenaltyBreakTemplateDeclaration
。
?
template <typename T> T foo() {
}
template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
MultiLine
僅在接下來的函數(shù)/類聲明參數(shù)需要跨行時(shí)才會(huì)在模板處斷行。
?
template <typename T> T foo() {
}
template <typename T>
T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
Yes
總是在模板聲明之后進(jìn)行斷行。
?
template <typename T>
T foo() {
}
template <typename T>
T foo(int aaaaaaaaaaaaaaaaaaaaa,
int bbbbbbbbbbbbbbbbbbbbb) {
}
2.26 AttributeMacros 屬性宏
應(yīng)該被解釋為屬性/限定符而不是標(biāo)識(shí)符的字符串向量。這對(duì)于語言擴(kuò)展或靜態(tài)分析器注釋非常有用。
下面是一個(gè)配置的例子:
?
x = (char *__capability)&y;
int function(void) __ununsed;
void only_writes_to_buffer(char *__output buffer);
.clang-format
配置文件,可以被配置成下面這樣:
?
AttributeMacros: ['__capability', '__output', '__ununsed']
#或者
AttributeMacros:
- __capability
- __output
- __ununsed
2.27 BinPackArguments 裝箱變量
如果為false
,函數(shù)調(diào)用變量要么都在同一行上,要么每個(gè)變量都獨(dú)自在一行。
如果true
,則會(huì)把變量合理打包放在一行上,顯得更緊湊。
?
true:
void f() {
f(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}
false:
void f() {
f(aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}
2.28 BinPackParameters 裝箱聲明參數(shù)
如果false
,函數(shù)聲明的參數(shù)或者函數(shù)定義的參數(shù)要么在同一行上,要么每個(gè)變量都獨(dú)自在一行。
如果true
,則會(huì)把變量合理打包放在一行上,顯得更緊湊。
?
true:
void f(int aaaaaaaaaaaaaaaaaaaa, int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
false:
void f(int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaa,
int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
2.29 BitFieldColonSpacing 位段列的空白風(fēng)格
可選以下值:Both
,None
,Before
,After
both
在:
號(hào)每邊都增加一個(gè)空白。
?
unsigned bf : 2;
None
不加任何空白,除了AlignConsecutiveBitFields
需要之外。
?
unsigned bf:2;
Before
僅在:
號(hào)之前添加空白。
?
unsigned bf :2;
After
僅在:
之后添加空白,除了AlignConsecutiveBitFields
需要在前面添加空白之外。
?
unsigned bf: 2;
2.30 BraceWrapping 大括號(hào)換行風(fēng)格
控制單獨(dú)的大括號(hào)換行情況。
如果breakbeforebrace
設(shè)置為BS_Custom
,則使用它來指定應(yīng)該如何處理每個(gè)獨(dú)立的大括號(hào)情況。否則,它將被忽略。
?
# Example of usage:
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: true
AfterStruct: false
SplitEmptyFunction: false
以下是具體的屬性設(shè)置。
bool AfterCaseLabel
,對(duì)case
后面的大括號(hào)換行。
?
false: true:
switch (foo) { vs. switch (foo) {
case 1: { case 1:
bar(); {
break; bar();
} break;
default: { }
plop(); default:
} {
} plop();
}
}
bool AfterClass
類定義換行。
?
true:
class foo
{};
false:
class foo {};
AfterControlStatement
,對(duì)語句if/for/while/switch/...
的換行風(fēng)格控制。
-
Never
在控制條件語句之后從不換行。if (foo()) {
} else {
}
for (int i = 0; i < 10; ++i) {
} -
MultiLine
只在一個(gè)多行控制語句之后換行。if (foo && bar &&
baz)
{
quux();
}
while (foo || bar) {
} -
Always
在控制語句之后總是換行。if (foo())
{
} else
{}
for (int i = 0; i < 10; ++i)
{}
bool AfterEnum
枚舉定義后大括號(hào)換行。
?
true:
enum X : int
{
B
};
false:
enum X : int { B };
bool AfterFunction
在函數(shù)定義之后大括號(hào)換行。
?
true:
void foo()
{
bar();
bar2();
}
false:
void foo() {
bar();
bar2();
}
bool AfterNamespace
命名空間后換行。
?
true:
namespace
{
int foo();
int bar();
}
false:
namespace {
int foo();
int bar();
}
bool AfterObjCDeclaration
在ObjC定義之后換行,@autoreleasepool 和 @synchronized
塊根據(jù)AfterControlStatement
標(biāo)志換行。
bool AfterStruct
結(jié)構(gòu)體定義之后換行。
?
true:
struct foo
{
int x;
};
false:
struct foo {
int x;
};
bool AfterUnion
聯(lián)合定義之后換行。
?
true:
union foo
{
int x;
}
false:
union foo {
int x;
}
bool AfterExternBlock
extern聲明之后換行。
?
true:
extern "C"
{
int foo();
}
false:
extern "C" {
int foo();
}
bool BeforeCatch
在catch
之前換行。
?
true:
try {
foo();
}
catch () {
}
false:
try {
foo();
} catch () {
}
bool BeforeElse
在else
之前換行。
?
true:
if (foo()) {
}
else {
}
false:
if (foo()) {
} else {
}
bool BeforeLambdaBody
在Lambda表達(dá)式塊之前換行。
?
true:
connect(
[]()
{
foo();
bar();
});
false:
connect([]() {
foo();
bar();
});
bool BeforeWhile
在while
之前換行。
?
true:
do {
foo();
}
while (1);
false:
do {
foo();
} while (1);
bool IndentBraces
對(duì)換行的大括號(hào)縮進(jìn)。
bool SplitEmptyFunction
如果為false,空函數(shù)體可以放在單行上。此選項(xiàng)僅在函數(shù)的左大括號(hào)已經(jīng)被換行的情況下使用,即設(shè)置了AfterFunction
大括號(hào)換行模式,并且函數(shù)不應(yīng)該放在單行上(根據(jù)AllowShortFunctionsOnASingleLine
和構(gòu)造函數(shù)格式選項(xiàng))。
?
false: true:
int f() vs. int f()
{} {
}
bool SplitEmptyRecord
如果為false,空記錄(例如類、結(jié)構(gòu)或聯(lián)合)主體可以放在單行上。此選項(xiàng)僅在記錄的開始大括號(hào)已經(jīng)被換行的情況下使用,即設(shè)置了AfterClass
(用于類)大括號(hào)換行模式。
?
false: true:
class Foo vs. class Foo
{} {
}
bool SplitEmptyNamespace
如果為false,空的namespace
主體可以放在單行上。此選項(xiàng)僅在命名空間的開始大括號(hào)已經(jīng)被換行的情況下使用,即設(shè)置了AfterNamespace
大括號(hào)換行模式。
?
false: true:
namespace Foo vs. namespace Foo
{} {
}
2.31 BreakAfterJavaFieldAnnotations 在修飾器之后斷行
?
true: false:
@Partial vs. @Partial @Mock DataLoad loader;
@Mock
DataLoad loader;
2.32 BreakArrays Json數(shù)組斷行
版本16支持,僅用于格式化Json數(shù)組。
如果為true, clang-format將總是在Json數(shù)組之后斷行,否則它將掃描到結(jié)束,以確定是否應(yīng)該在元素之間添加換行符(兼容更漂亮的格式)。
?
true: false:
[ vs. [1, 2, 3, 4]
1,
2,
3,
4
]
2.33 BreakBeforeBinaryOperators 二元操作符斷行
用于對(duì)二元操作符斷行,支持以下選項(xiàng):
None
在操作符之后斷行。
?
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >
ccccccccccccccccccccccccccccccccccccccccc;
NonAssignment
只在非賦值操作符之前斷行。
?
LooooooooooongType loooooooooooooooooooooongVariable =
someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
All
在操作符之前斷行。
?
LooooooooooongType loooooooooooooooooooooongVariable
= someLooooooooooooooooongFunction();
bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
== aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
> ccccccccccccccccccccccccccccccccccccccccc;
2.34 BreakBeforeBraces 大括號(hào)斷行風(fēng)格
指定大括號(hào)斷行風(fēng)格,有以下的選項(xiàng)。
Attach
總是將大括號(hào)附加到周圍的上下文。
?
namespace N {
enum E {
E1,
E2,
};
class C {
public:
C();
};
bool baz(int i) {
try {
do {
switch (i) {
case 1: {
foobar();
break;
}
default: {
break;
}
}
} while (--i);
return true;
} catch (...) {
handleError();
return false;
}
}
void foo(bool b) {
if (b) {
baz(2);
} else {
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Linux
和Attach
類似,但是會(huì)在函數(shù)、命名空間namespace
和類定義之前換行。
?
namespace N
{
enum E {
E1,
E2,
};
class C
{
public:
C();
};
bool baz(int i)
{
try {
do {
switch (i) {
case 1: {
foobar();
break;
}
default: {
break;
}
}
} while (--i);
return true;
} catch (...) {
handleError();
return false;
}
}
void foo(bool b)
{
if (b) {
baz(2);
} else {
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Mozilla
和Attach
類似,但是會(huì)在枚舉、函數(shù)、record定義之前換行。
?
namespace N {
enum E
{
E1,
E2,
};
class C
{
public:
C();
};
bool baz(int i)
{
try {
do {
switch (i) {
case 1: {
foobar();
break;
}
default: {
break;
}
}
} while (--i);
return true;
} catch (...) {
handleError();
return false;
}
}
void foo(bool b)
{
if (b) {
baz(2);
} else {
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Stroustrup
和Attach
類似,但是在函數(shù)定義、catch
、else
之前換行。
?
namespace N {
enum E {
E1,
E2,
};
class C {
public:
C();
};
bool baz(int i)
{
try {
do {
switch (i) {
case 1: {
foobar();
break;
}
default: {
break;
}
}
} while (--i);
return true;
}
catch (...) {
handleError();
return false;
}
}
void foo(bool b)
{
if (b) {
baz(2);
}
else {
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Allman
總是會(huì)在大括號(hào)之前斷行。
?
namespace N
{
enum E
{
E1,
E2,
};
class C
{
public:
C();
};
bool baz(int i)
{
try
{
do
{
switch (i)
{
case 1:
{
foobar();
break;
}
default:
{
break;
}
}
} while (--i);
return true;
}
catch (...)
{
handleError();
return false;
}
}
void foo(bool b)
{
if (b)
{
baz(2);
}
else
{
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Whitesmiths
和Allman
類似,但是始終要縮進(jìn)大括號(hào)并使用大括號(hào)排列代碼。
?
namespace N
{
enum E
{
E1,
E2,
};
class C
{
public:
C();
};
bool baz(int i)
{
try
{
do
{
switch (i)
{
case 1:
{
foobar();
break;
}
default:
{
break;
}
}
} while (--i);
return true;
}
catch (...)
{
handleError();
return false;
}
}
void foo(bool b)
{
if (b)
{
baz(2);
}
else
{
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
GNU
總是在大括號(hào)之前斷行,并在控制語句的大括號(hào)中增加額外的縮進(jìn)級(jí)別,而在類、函數(shù)或其他定義的大括號(hào)中不會(huì)縮進(jìn)大括號(hào)。
?
namespace N
{
enum E
{
E1,
E2,
};
class C
{
public:
C();
};
bool baz(int i)
{
try
{
do
{
switch (i)
{
case 1:
{
foobar();
break;
}
default:
{
break;
}
}
}
while (--i);
return true;
}
catch (...)
{
handleError();
return false;
}
}
void foo(bool b)
{
if (b)
{
baz(2);
}
else
{
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
WebKit
和Attach
類似,但是在函數(shù)之前斷行。
?
namespace N {
enum E {
E1,
E2,
};
class C {
public:
C();
};
bool baz(int i)
{
try {
do {
switch (i) {
case 1: {
foobar();
break;
}
default: {
break;
}
}
} while (--i);
return true;
} catch (...) {
handleError();
return false;
}
}
void foo(bool b)
{
if (b) {
baz(2);
} else {
baz(5);
}
}
void bar() { foo(true); }
} // namespace N
Custom
,客制化配置每個(gè)大括號(hào)的情況。
2.35 BreakBeforeConceptDeclarations 概念聲明斷行風(fēng)格
有以下幾種選項(xiàng):
Never
保持模板聲明行和concept
在一起。
?
template <typename T> concept C = ...;
Allowed
允許在模板聲明和concept
之間斷行,實(shí)際的表現(xiàn)取決于上下文和斷行規(guī)則。
Always
永遠(yuǎn)在concept
之前斷行,并且將該行放在模板聲明之前。
?
template <typename T>
concept C = ...;
2.36 BreakBeforeTernaryOperators 三元操作符斷行規(guī)則
如果為true,三元操作符將放在換行符之后。
?
true:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
? firstValue
: SecondValueVeryVeryVeryVeryLong;
false:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
firstValue :
SecondValueVeryVeryVeryVeryLong;
2.37 BreakConstructorInitializers 構(gòu)造初始化斷行風(fēng)格
有以下幾種風(fēng)格:
BeforeColon
斷行冒號(hào)前和逗號(hào)后的構(gòu)造函數(shù)初始化式
?
Constructor()
: initializer1(),
initializer2()
BeforeComma
在冒號(hào)和逗號(hào)之前斷行構(gòu)造函數(shù)的初始化式,并將逗號(hào)與冒號(hào)對(duì)齊。
?
Constructor()
: initializer1()
, initializer2()
AfterColon
在冒號(hào)和逗號(hào)后面斷行構(gòu)造函數(shù)初始化式。
?
Constructor() :
initializer1(),
initializer2()
2.38 BreakInheritanceList 繼承鏈斷行風(fēng)格
有以下選項(xiàng)。
BeforeColon
在冒號(hào)之前,逗號(hào)之后斷行繼承鏈。
?
class Foo
: Base1,
Base2
{};
BeforeComma
在冒號(hào)和逗號(hào)之前斷行,并且對(duì)齊它們。
?
class Foo
: Base1
, Base2
{};
AfterColon
在冒號(hào)和逗號(hào)之后斷行。
?
class Foo :
Base1,
Base2
{};
AfterComma
僅在逗號(hào)之后進(jìn)行斷行。
?
class Foo : Base1,
Base2
{};
2.39 BreakStringLiterals 字符串常量斷行
允許對(duì)字符串字面量進(jìn)行斷行。
?
true:
const char* x = "veryVeryVeryVeryVeryVe"
"ryVeryVeryVeryVeryVery"
"VeryLongString";
false:
const char* x =
"veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
2.40 ColumnLimit 列數(shù)限制
列限制為0表示沒有列限制。在這種情況下,clang-format將尊重語句中的輸入斷行決定,除非它們與其他規(guī)則相沖突。
即在列數(shù)最大值為0時(shí),則不會(huì)進(jìn)行一行語句太長導(dǎo)致的換行。
2.41 CommentPragmas 注釋表示
值為字符串,含有正則表達(dá)式,其描述具有特殊含義的注釋,這些注釋不應(yīng)被分割成行或以其他方式更改。
?
CommentPragmas: '^ FOOBAR pragma:'
?
?
// Will leave the following line unaffected
#include <vector> // FOOBAR pragma: keep
2.42 CompactNamespaces 緊湊命名空間
如果為true,則連續(xù)的名稱空間聲明將在同一行上。如果為false,則每個(gè)名稱空間都在新行中聲明。
?
true:
namespace Foo { namespace Bar {
}}
false:
namespace Foo {
namespace Bar {
}
}
如果一行放不下,那么就會(huì)換行。
?
namespace Foo { namespace Bar {
namespace Extra {
}}}
2.43 ConstructorInitializerAllOnOneLineOrOnePerLine 構(gòu)造初始化斷行風(fēng)格
選項(xiàng)已棄用, See CurrentLine
of PackConstructorInitializers
.
2.44 ConstructorInitializerIndentWidth 構(gòu)造初始化縮進(jìn)寬度
用于構(gòu)造函數(shù)初始化列表和繼承列表縮進(jìn)的字符數(shù),無符號(hào)整數(shù)。
2.45 ContinuationIndentWidth
延續(xù)下一行的縮進(jìn)寬度,只原來一行放不下時(shí),換行后,新行縮進(jìn)的字符數(shù)。
?
ContinuationIndentWidth: 2
int i = // VeryVeryVeryVeryVeryLongComment
longFunction( // Again a long comment
arg);
2.46 Cpp11BracedListStyle 大括號(hào)列表風(fēng)格
重要區(qū)別:
- 括號(hào)列表中沒有空格。
- 在結(jié)束大括號(hào)前不能換行。
- 用連續(xù)縮進(jìn),而不是用塊縮進(jìn)。
基本上,c++ 11的大括號(hào)列表的格式與函數(shù)調(diào)用的格式完全相同。如果括號(hào)列表后面跟著一個(gè)名稱(例如類型或變量名),clang-
format的格式就像{}是帶有該名稱的函數(shù)調(diào)用的圓括號(hào)一樣。如果沒有名稱,則假定名稱長度為零。
?
true: false:
vector<int> x{1, 2, 3, 4}; vs. vector<int> x{ 1, 2, 3, 4 };
vector<T> x{{}, {}, {}, {}}; vector<T> x{ {}, {}, {}, {} };
f(MyMap[{composite, key}]); f(MyMap[{ composite, key }]);
new int[3]{1, 2, 3}; new int[3]{ 1, 2, 3 };
2.47 DeriveLineEnding 提取行結(jié)尾
分析格式化文件中最常用的行結(jié)尾(\r\n或\n)。UseCRLF
僅在無法派生任何方法時(shí)用作備用。
2.48 DerivePointerAlignment 提取指針對(duì)齊
如果為true,分析格式化文件中&
和*
最常見的對(duì)齊方式。指針和引用對(duì)齊樣式將根據(jù)在文件中找到的首選項(xiàng)進(jìn)行更新。然后,只將PointerAlignment
用作備用。
2.49 DisableFormat 禁用格式化
完全禁用格式化。
2.50 EmptyLineAfterAccessModifier 訪問修飾符后空行
定義何時(shí)在訪問修飾符之后放置空行。EmptyLineBeforeAccessModifier
配置處理兩個(gè)訪問修飾符之間的空行數(shù)。
有以下的選項(xiàng):
Never
移除訪問修飾符之后所有的空行。
?
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {}
private:
protected:
};
Leave
在訪問修飾符之后保持現(xiàn)有的空行。取而代之的是MaxEmptyLinesToKeep。
Always
如果沒有訪問修飾符,總是在后面添加空行。MaxEmptyLinesToKeep也被應(yīng)用。
?
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {}
private:
protected:
};
2.51 EmptyLineBeforeAccessModifier 訪問修飾符前空行
有以下選項(xiàng):
Never
移除訪問修飾符之前的所有空行。
?
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {}
private:
protected:
};
leave
保留在訪問符之間的空行。
LogicalBlock
只有當(dāng)訪問修飾符開始一個(gè)新的邏輯塊時(shí)才添加空行。邏輯塊是由一個(gè)或多個(gè)成員字段或函數(shù)組成的一組。
?
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {}
private:
protected:
};
Always
總是在訪問修飾符之前添加空行,除非訪問修飾符位于結(jié)構(gòu)或類定義的開頭。
?
struct foo {
private:
int i;
protected:
int j;
/* comment */
public:
foo() {}
private:
protected:
};
2.52 ExperimentalAutoDetectBinPacking
實(shí)現(xiàn)性功能。
如果為true, clang-format將檢測函數(shù)調(diào)用和定義是否使用每行一個(gè)參數(shù)進(jìn)行格式化。
每個(gè)調(diào)用可以打包,每行一個(gè)或不確定。如果它是不確定的,例如完全在一行上,但需要做出決定,clang-
format分析輸入文件中是否有其他打包情況,并相應(yīng)地采取行動(dòng)。
注意:這是一個(gè)實(shí)驗(yàn)標(biāo)志,它可能會(huì)消失或被重命名。不要在配置文件中使用它,等等。使用風(fēng)險(xiǎn)自負(fù)。
2.53 FixNamespaceComments 修復(fù)命名空間描述
如果為true, clang-
format將為短名稱空間添加丟失的“名稱空間的結(jié)束注釋”并修復(fù)無效的現(xiàn)有注釋。短命名空間的換行風(fēng)格由“ShortNamespaceLines”控制。
?
true: false:
namespace a { vs. namespace a {
foo(); foo();
bar(); bar();
} // namespace a }
2.54 ForEachMacros 迭代循環(huán)宏
應(yīng)該被解釋為foreach循環(huán)而不是函數(shù)調(diào)用的宏向量。
它們應(yīng)該具有以下的宏定義形式:
?
FOREACH(<variable-declaration>, ...)
<loop-body>
在.clang-format
配置文件里,可以被配置成以下形式:
?
ForEachMacros: ['RANGES_FOR', 'FOREACH']
2.55 IfMacros 條件判斷宏
一組宏應(yīng)該被解釋為條件語句而不是函數(shù)調(diào)用。
它們應(yīng)該具有以下的形式:
?
IF(...)
<conditional-body>
else IF(...)
<conditional-body>
在.clang-format
配置文件里,可以被配置成以下形式:
?
IfMacros: ['IF']
2.56 IncludeBlocks include
塊風(fēng)格
根據(jù)該值,多個(gè)#include
塊可以被排序?yàn)橐粋€(gè),并根據(jù)類別進(jìn)行劃分。
Preserve
,每個(gè)#include
塊單獨(dú)排序。
?
#include "b.h" into #include "b.h"
#include <lib/main.h> #include "a.h"
#include "a.h" #include <lib/main.h>
Merge
合并多個(gè)#include
塊,并且整體排序。
?
#include "b.h" into #include "a.h"
#include "b.h"
#include <lib/main.h> #include <lib/main.h>
#include "a.h"
Regroup
合并多個(gè)#include
塊,并且整體排序,然后根據(jù)類別優(yōu)先級(jí)分組,可查詢IncludeCategories
。
?
#include "b.h" into #include "a.h"
#include "b.h"
#include <lib/main.h>
#include "a.h" #include <lib/main.h>
2.57 IncludeCategories include
種類
正則表達(dá)式表示不同的#include
類別,用于對(duì)#includes
進(jìn)行排序。
支持POSIX擴(kuò)展正則表達(dá)式(ERE)。
這些正則表達(dá)式按順序匹配include
的文件名(包括<>
或" "
)。對(duì)匹配上的第一個(gè)匹配正則表達(dá)式的值進(jìn)行賦值,#include
首先根據(jù)類別數(shù)量的增加排序,然后在每個(gè)類別內(nèi)按字母順序排序。
如果沒有匹配的正則表達(dá)式,則賦值INT_MAX,并作為類別。 源文件的主頭文件自動(dòng)獲得類別0 。因此它通常被保存在#includes
(https://llvm.org/docs/CodingStandards.html#include-style)的開頭。但是,
如果您有某些頭文件總是需要放在首位,您也可以分配負(fù)優(yōu)先級(jí) 。
在IncludeBlocks = IBS_Regroup
時(shí),可以使用第三個(gè)可選字段SortPriority
來定義優(yōu)先級(jí),其中#includes
應(yīng)該排序。Priority
的值定義了#include
塊的順序,還允許對(duì)具有不同優(yōu)先級(jí)的#include
進(jìn)行分組。如果沒有分配,SortPriority
將被設(shè)置為Priority
的默認(rèn)值。
每個(gè)正則表達(dá)式都可以用CaseSensitive
字段標(biāo)記為區(qū)分大小寫,默認(rèn)情況下不區(qū)分大小寫。
可以像下面這樣配置.clang-format
文件。
?
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 2
CaseSensitive: true
- Regex: '^((<|")(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '<[[:alnum:].]+>'
Priority: 4
- Regex: '.*'
Priority: 1
SortPriority: 0
2.58 IncludeIsMainRegex 判斷主包含的正則表達(dá)式
指定一個(gè)正則表達(dá)式,其表明了文件到主包含映射中被允許的后綴名。
當(dāng)猜測一個(gè)#include
是否為“main” include
(分配類別0,見上文)時(shí),使用這個(gè)由允許后綴名組成的正則表達(dá)式到主干部分。部分匹配完成,因此:
-
""
表示“任意后綴” -
"$"
表示“無后綴”
例如,如果配置為“(_test)?”$ “,則頭文件a.h
將被視為a.cc
和a_test.cc
中的"主包含”。
2.59 IncludeIsMainSourceRegex 判斷源文件的正則表達(dá)式
為被格式化的文件指定正則表達(dá)式,匹配正則表達(dá)式的這些文件允許在文件到main-include
映射中被視為“main”。
默認(rèn)情況下,clang-format認(rèn)為只有當(dāng)文件以.c
, .cc
, .cpp
, .c++
, .cxx
, .m
或.mm
擴(kuò)展名結(jié)尾時(shí),文件才是" main
"。對(duì)于這些文件,將進(jìn)行“main”include的猜測(分配類別0,參見上面)。該配置選項(xiàng)允許為被視為“main”的文件添加額外的后綴和擴(kuò)展名。
例如,如果這個(gè)選項(xiàng)被配置為(Impl.hpp)$
,那么一個(gè)文件classimple .hpp
被認(rèn)為是" main "(此外還有Class.c
,Class.c
, Class.cpp
)和“main include
file”邏輯將被執(zhí)行(IncludeIsMainRegex
設(shè)置在后面的階段也會(huì)被執(zhí)行)。如果沒有設(shè)置這個(gè)選項(xiàng),classimple .hpp
就不會(huì)把主包含文件放在任何其他包含文件之前。
2.60 IndentAccessModifiers 訪問修飾符縮進(jìn)
指定訪問修飾符是否應(yīng)該有自己的縮進(jìn)級(jí)別。
當(dāng)為false時(shí),訪問修飾符相對(duì)于記錄成員縮進(jìn)(或向外縮進(jìn)),根據(jù)AccessModifierOffset
。記錄成員的縮進(jìn)位置比記錄低一級(jí)。當(dāng)為true時(shí),訪問修飾符獲得自己的縮進(jìn)級(jí)別。因此,無論是否存在訪問修飾符,記錄成員總是在記錄下方縮進(jìn)2級(jí)。AccessModifierOffset
的值被忽略。
?
false: true:
class C { vs. class C {
class D { class D {
void bar(); void bar();
protected: protected:
D(); D();
}; };
public: public:
C(); C();
}; };
void foo() { void foo() {
return 1; return 1;
} }
2.61 IndentCaseBlocks case
塊縮進(jìn)
縮進(jìn)case label
將case label
隔一層。
當(dāng)為false
時(shí),case
標(biāo)簽后面的塊使用與case
標(biāo)簽相同的縮進(jìn)級(jí)別,將case
標(biāo)簽視為if
語句。當(dāng)為true時(shí),該塊縮進(jìn)為作用域塊。
?
false: true:
switch (fool) { vs. switch (fool) {
case 1: case 1:
bar(); bar();
break; break;
default: default:
plop(); plop();
} }
2.62 IndentExternBlock Extern
擴(kuò)展塊縮進(jìn)
有以下的選線:
AfterExternBlock
向后兼容AfterExternBlock
的縮進(jìn),即按BraceWrapping.AfterExternBlock
設(shè)置來進(jìn)行格式化。
?
IndentExternBlock: AfterExternBlock
BraceWrapping.AfterExternBlock: true
extern "C"
{
void foo();
}
?
?
IndentExternBlock: AfterExternBlock
BraceWrapping.AfterExternBlock: false
extern "C" {
void foo();
}
NoIndent
不縮進(jìn)extern
擴(kuò)展塊
?
extern "C" {
void foo();
}
Indent
縮進(jìn)extern
擴(kuò)展塊
?
extern "C" {
void foo();
}
2.63 IndentGotoLabels 縮進(jìn)Goto
跳轉(zhuǎn)符號(hào)
?
true: false:
int f() { vs. int f() {
if (foo()) { if (foo()) {
label1: label1:
bar(); bar();
} }
label2: label2:
return 1; return 1;
} }
2.64 IndentPPDirectives 預(yù)處理指令縮進(jìn)
要使用的預(yù)處理器指令縮進(jìn)樣式。
None
不縮進(jìn)任何預(yù)處理器指示符。
?
#if FOO
#if BAR
#include <foo>
#endif
#endif
AfterHash
縮進(jìn)散列之后的指令。
?
#if FOO
# if BAR
# include <foo>
# endif
#endif
BeforeHash
縮進(jìn)散列之前的指令
?
#if FOO
#if BAR
#include <foo>
#endif
#endif
2.65 IndentRequiresClause 縮進(jìn)要求子句
縮進(jìn)模板中的require子句。這只適用于RequiresClausePosition
為OwnLine
或WithFollowing
時(shí)。
在一些版本中,其名字為IndentRequires
。
?
true:
template <typename It>
requires Iterator<It>
void sort(It begin, It end) {
//....
}
false:
template <typename It>
requires Iterator<It>
void sort(It begin, It end) {
//....
}
2.66 IndentWidth 縮進(jìn)寬度
用于縮進(jìn)的列數(shù)。
?
IndentWidth: 3
void f() {
someFunction();
if (true, false) {
f();
}
}
2.67 IndentWrappedFunctionNames 函數(shù)名縮進(jìn)
如果函數(shù)定義或聲明在類型之后換行,則縮進(jìn)。
?
true:
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration();
false:
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration();
2.68 InsertBraces 插入括號(hào)
在c++中,在控制語句(if、else、for、do和while)后面插入大括號(hào),除非控制語句在宏定義中,或者大括號(hào)包含預(yù)處理程序指令。
將此選項(xiàng)設(shè)置為true可能導(dǎo)致錯(cuò)誤的代碼格式,因?yàn)閏lang-format缺乏完整的語義信息。因此,在檢查此選項(xiàng)所做的代碼更改時(shí)應(yīng)格外小心。
?
false: true:
if (isa<FunctionDecl>(D)) vs. if (isa<FunctionDecl>(D)) {
handleFunctionDecl(D); handleFunctionDecl(D);
else if (isa<VarDecl>(D)) } else if (isa<VarDecl>(D)) {
handleVarDecl(D); handleVarDecl(D);
else } else {
return; return;
}
while (i--) vs. while (i--) {
for (auto *A : D.attrs()) for (auto *A : D.attrs()) {
handleAttr(A); handleAttr(A);
}
}
do vs. do {
--i; --i;
while (i); } while (i);
2.69 InsertTrailingCommas 摻入尾部冒號(hào)
如果設(shè)置為TCS_Wrapped,則會(huì)在跨多行換行的容器字面量(數(shù)組和對(duì)象)中插入尾隨逗號(hào)。它目前只對(duì)JavaScript可用,默認(rèn)禁用TCS_None
。inserttrailingcomma
不能與BinPackArguments
一起使用,因?yàn)椴迦攵禾?hào)將禁用bin- packing
。
?
TSC_Wrapped:
const someArray = [
aaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaa,
// ^ inserted
]
可以選None
或者Wrapped
。
2.70 JavaImportGroups
為Java導(dǎo)入按所需組排序的前綴向量。
一個(gè)組的前綴可以是另一個(gè)組的前綴子集——最長的前綴總是匹配的。在一個(gè)組中,導(dǎo)入是按字典順序排列的。靜態(tài)導(dǎo)入被單獨(dú)分組,并遵循相同的分組規(guī)則。默認(rèn)情況下,靜態(tài)導(dǎo)入放置在非靜態(tài)導(dǎo)入之前,但是這種行為由另一個(gè)選項(xiàng)SortJavaStaticImport
改變。
在.clang-format
的配置文件中,可以像下面的yaml
示例那樣進(jìn)行配置。這將導(dǎo)致導(dǎo)入的格式如下面的Java示例所示。
?
JavaImportGroups: ['com.example', 'com', 'org']
?
?
import static com.example.function1;
import static com.test.function2;
import static org.example.function3;
import com.example.ClassA;
import com.example.Test;
import com.example.a.ClassB;
import com.test.ClassC;
import org.example.ClassD;
2.71 JavaScriptQuotes Java引號(hào)風(fēng)格
有以下選項(xiàng):
Leave
保持原始值不變。
?
string1 = "foo";
string2 = 'bar';
Single
總是使用單引號(hào)。
?
string1 = 'foo';
string2 = 'bar';
Double
總是使用雙引號(hào)。
?
string1 = "foo";
string2 = "bar";
2.72 JavaScriptWrapImports import/export
語句換行
?
true:
import {
VeryLongImportsAreAnnoying,
VeryLongImportsAreAnnoying,
VeryLongImportsAreAnnoying,
} from 'some/module.js'
false:
import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
2.73 KeepEmptyLinesAtTheStartOfBlocks 在語法塊開始留空行
?
true: false:
if (foo) { vs. if (foo) {
bar();
bar(); }
}
2.74 LambdaBodyIndentation Lambda表達(dá)式主體縮進(jìn)
lambda
體的縮進(jìn)樣式。Signature
(默認(rèn)值)導(dǎo)致lambda
體相對(duì)于簽名的縮進(jìn)級(jí)別額外縮進(jìn)一個(gè)級(jí)別。OuterScope
強(qiáng)制lambda
主體相對(duì)于包含lambda
簽名的父作用域額外縮進(jìn)一級(jí)。對(duì)于回調(diào)較多的代碼,將簽名縮進(jìn)兩層并使用OuterScope
可能會(huì)提高可讀性。KJ風(fēng)格指南需要OuterScope
。
可能的值:
Signature
將lambda主體相對(duì)于lambda簽名對(duì)齊。這是默認(rèn)設(shè)置。
?
someMethod(
[](SomeReallyLongLambdaSignatureArgument foo) {
return;
});
OuterScope
相對(duì)于lambda簽名所在的外部作用域的縮進(jìn)級(jí)別對(duì)齊lambda主體。
?
someMethod(
[](SomeReallyLongLambdaSignatureArgument foo) {
return;
});
2.75 Language 目標(biāo)格式化編程語言
可能的值:
None
,Cpp
,CSharp
,Java
,JavaScript
,Json
,Objc
,Proto
,TableGen
,TextProto
,Verilog
。
2.76 MacroBlockBegin 開始?jí)K的宏
匹配啟動(dòng)塊的宏的正則表達(dá)式。
?
# With:
MacroBlockBegin: "^NS_MAP_BEGIN|\
NS_TABLE_HEAD$"
MacroBlockEnd: "^\
NS_MAP_END|\
NS_TABLE_.*_END$"
NS_MAP_BEGIN
foo();
NS_MAP_END
NS_TABLE_HEAD
bar();
NS_TABLE_FOO_END
# Without:
NS_MAP_BEGIN
foo();
NS_MAP_END
NS_TABLE_HEAD
bar();
NS_TABLE_FOO_END
2.77 MacroBlockEnd 結(jié)束塊的宏
詳情見2.76 MacroBlockBegin
。
2.78 MaxEmptyLinesToKeep 最大持續(xù)空行
要保留的連續(xù)空行的最大數(shù)目。
?
MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0
int f() { int f() {
int = 1; int i = 1;
i = foo();
i = foo(); return i;
}
return i;
}
2.79 NamespaceIndentation 命名空間縮進(jìn)
有以下的選項(xiàng):
None
,不縮進(jìn)命名空間。
?
namespace out {
int i;
namespace in {
int i;
}
}
Inner
只縮進(jìn)嵌套的命名空間。
?
namespace out {
int i;
namespace in {
int i;
}
}
All
縮進(jìn)所有的命名空間。
?
namespace out {
int i;
namespace in {
int i;
}
}
2.80 NamespaceMacro 命名空間宏
用于打開名稱空間塊的宏向量。
這些被期望為如下形式的宏:
?
NAMESPACE(<namespace-name>, ...) {
<namespace-content>
}
2.81 ObjCBinPackProtocolList Objective-C打包風(fēng)格
當(dāng)object - c
協(xié)議一致性列表項(xiàng)超過ColumnLimit
時(shí),控制將它們打包成盡可能少的行。
如果Auto
(默認(rèn)值),則委托給BinPackParameters
中的值。如果這是正確的,那么當(dāng)object -
c協(xié)議一致性列表項(xiàng)超過ColumnLimit
時(shí),會(huì)將它們打包成盡可能少的行。
如果Always
, 當(dāng)它們超過ColumnLimit
時(shí),就會(huì)將Objective-C
協(xié)議一致性列表項(xiàng)打包成盡可能少的行。
如果Never
,則在超出ColumnLimit
時(shí)將Objective-C
協(xié)議一致性列表項(xiàng)布局到單獨(dú)的行上。
?
Always (or Auto, if BinPackParameters=true):
@interface ccccccccccccc () <
ccccccccccccc, ccccccccccccc,
ccccccccccccc, ccccccccccccc> {
}
Never (or Auto, if BinPackParameters=false):
@interface ddddddddddddd () <
ddddddddddddd,
ddddddddddddd,
ddddddddddddd,
ddddddddddddd> {
}
2.82 ObjCBlockIndentWidth ObjC塊縮進(jìn)
用于ObjC塊縮進(jìn)的字符數(shù)。
?
ObjCBlockIndentWidth: 4
[operation setCompletionBlock:^{
[self onOperationDone];
}];
2.83 ObjCBreakBeforeNestedBlockParam 分解嵌套塊參數(shù)
當(dāng)函數(shù)調(diào)用中有嵌套的塊參數(shù)時(shí),將參數(shù)列表分解成行。
?
false:
- (void)_aMethod
{
[self.test1 t:self w:self callback:^(typeof(self) self, NSNumber
*u, NSNumber *v) {
u = c;
}]
}
true:
- (void)_aMethod
{
[self.test1 t:self
w:self
callback:^(typeof(self) self, NSNumber *u, NSNumber *v) {
u = c;
}]
}
2.84 ObjCSpaceAfterProperty 屬性修飾符空格
在Objective-C中在@property后面添加一個(gè)空格,即使用@property (readonly)
而不是@property(readonly)
。
2.85 ObjCSpaceBeforeProtocolList 協(xié)議列表前空白
在Objective-C協(xié)議列表前面添加一個(gè)空格,即使用Foo <protocol>
而不是Foo<protocol>
。
2.86 PPIndentWidth 預(yù)處理符號(hào)縮進(jìn)指定
用于預(yù)處理器語句縮進(jìn)的列數(shù)。當(dāng)IndentWidth
設(shè)置為-1
(默認(rèn)值)時(shí),IndentWidth
也用于預(yù)處理器語句。
?
PPIndentWidth: 1
#ifdef __linux__
# define FOO
#else
# define BAR
#endif
2.87 PackConstructorInitializers 打包構(gòu)造器初始化列表
有以下的選項(xiàng):
Never
總是將每個(gè)構(gòu)造函數(shù)初始化列表放在單獨(dú)的一行上。
?
Constructor()
: a(),
b()
BinPack
打包構(gòu)造函數(shù)初始化列表。
?
Constructor()
: aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(),
cccccccccccccccccccc()
CurrentLine
如果合適,將所有構(gòu)造函數(shù)初始化式放在當(dāng)前行中。否則,將每一個(gè)放在單獨(dú)的一行上。
?
Constructor() : a(), b()
Constructor()
: aaaaaaaaaaaaaaaaaaaa(),
bbbbbbbbbbbbbbbbbbbb(),
ddddddddddddd()
NextLine
與PCIS_CurrentLine相同的是,如果所有的構(gòu)造函數(shù)初始化式都不適合當(dāng)前行,則嘗試將它們適合下一行。
?
Constructor() : a(), b()
Constructor()
: aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
Constructor()
: aaaaaaaaaaaaaaaaaaaa(),
bbbbbbbbbbbbbbbbbbbb(),
cccccccccccccccccccc()
2.88 PenaltyXxxx 各類情況的懲罰
(個(gè)人猜測是不同格式化情況的優(yōu)先級(jí)情況,數(shù)值越高,優(yōu)先級(jí)越大)
詳情參考原文檔:Clang-Format Style Options — Clang 16.0.0git documentation
(llvm.org)
2.89 PointerAlignment 指針對(duì)齊風(fēng)格
可選以下選項(xiàng):
Left
向左對(duì)齊指針。
?
int* a;
Right
向右對(duì)齊指針。
?
int *a;
Middle
中間對(duì)齊指針。
?
int * a;
2.90 QualifierAlignment 限定符對(duì)齊
不同的排列說明符和限定符的方法(例如const/volatile)。
將QualifierAlignment設(shè)置為Leave以外的值,可能會(huì)導(dǎo)致由于clang-
formats缺乏完整的語義信息而做出的錯(cuò)誤決策而導(dǎo)致錯(cuò)誤的代碼格式。因此,在檢查使用此選項(xiàng)所做的代碼更改時(shí)應(yīng)格外小心。
有以下選項(xiàng):
Leave
保持原狀,不強(qiáng)制左或右對(duì)齊。
?
int const a;
const int *a;
Left
左對(duì)齊說明符和限定符。
?
const int a;
const int *a;
Right
右對(duì)齊說明符和限定符。
?
int const a;
int const *a;
Custom
將說明符/限定符更改為基于QualifierOrder對(duì)齊。
?
QualifierOrder: ['inline', 'static', 'type', 'const']
int const a;
int const *a;
2.91 QualifierOrder 說明/限定符順序
限定符出現(xiàn)的順序。Order是一個(gè)數(shù)組,可以包含以下任何一個(gè):
?
const, inline, static, constexpr, volatile, restrict, type
注意:它必須包含’ type ‘。在’ type
'左邊的項(xiàng)目將被放置在類型的左邊,并按提供的順序排列。“類型”右側(cè)的項(xiàng)目將被放置在類型的右側(cè),并按提供的順序排列。
?
QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ]
2.92 RawStringFormats 原始字符串格式
定義在原始字符串中檢測支持的語言代碼塊的提示。
具有匹配分隔符或匹配封閉函數(shù)名的原始字符串將根據(jù).clang-format
文件中定義的指定語言的樣式進(jìn)行重新格式化。如果在.clang- format
文件中沒有為特定語言定義樣式,則使用BasedOnStyle
給出的預(yù)定義樣式。如果沒有找到BasedOnStyle
,則格式化基于llvm樣式。在確定原始字符串內(nèi)容的語言時(shí),匹配的分隔符優(yōu)先于匹配的封閉函數(shù)名。
如果指定了規(guī)范分隔符,則同一語言中出現(xiàn)的其他分隔符將盡可能更新為規(guī)范分隔符。
每種語言最多應(yīng)該有一個(gè)規(guī)范,每個(gè)分隔符和封閉函數(shù)不應(yīng)該出現(xiàn)在多個(gè)規(guī)范中。
要在.clang-format
文件中配置這個(gè),使用:
?
RawStringFormats:
- Language: TextProto
Delimiters:
- 'pb'
- 'proto'
EnclosingFunctions:
- 'PARSE_TEXT_PROTO'
BasedOnStyle: google
- Language: Cpp
Delimiters:
- 'cc'
- 'cpp'
BasedOnStyle: llvm
CanonicalDelimiter: 'cc'
2.93 ReferenceAlignment 引用對(duì)齊格式
引用對(duì)齊樣式(對(duì)于引用其覆蓋了PointerAlignment
選項(xiàng))。
有以下可能的選項(xiàng):
Pointer
,引用對(duì)齊風(fēng)格和PointerAlignment
一致。
Left
向左對(duì)齊。
?
int& a;
Right
向右對(duì)齊。
?
int &a;
Middle
在中間對(duì)齊。
?
int & a;
2.94 ReflowComments 重排版注釋
如果為true
,clang-format會(huì)重新排版注釋。
?
false:
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
true:
// veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
// information
/* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
* information */
2.95 RemoveBracesLLVM 移除括號(hào)
這個(gè)功能是用來移除部分可以去掉的括號(hào)(大括號(hào)),即if
/else
/for
/while
等語句。通過LLVM風(fēng)格實(shí)現(xiàn)。
該選項(xiàng)可能被修改名稱以支持更多的風(fēng)格。
該選項(xiàng)可能帶來未知的錯(cuò)誤,需要小心使用 。
?
false: true:
if (isa<FunctionDecl>(D)) { vs. if (isa<FunctionDecl>(D))
handleFunctionDecl(D); handleFunctionDecl(D);
} else if (isa<VarDecl>(D)) { else if (isa<VarDecl>(D))
handleVarDecl(D); handleVarDecl(D);
}
if (isa<VarDecl>(D)) { vs. if (isa<VarDecl>(D)) {
for (auto *A : D.attrs()) { for (auto *A : D.attrs())
if (shouldProcessAttr(A)) { if (shouldProcessAttr(A))
handleAttr(A); handleAttr(A);
} }
}
}
if (isa<FunctionDecl>(D)) { vs. if (isa<FunctionDecl>(D))
for (auto *A : D.attrs()) { for (auto *A : D.attrs())
handleAttr(A); handleAttr(A);
}
}
if (auto *D = (T)(D)) { vs. if (auto *D = (T)(D)) {
if (shouldProcess(D)) { if (shouldProcess(D))
handleVarDecl(D); handleVarDecl(D);
} else { else
markAsIgnored(D); markAsIgnored(D);
} }
}
if (a) { vs. if (a)
b(); b();
} else { else if (c)
if (c) { d();
d(); else
} else { e();
e();
}
}
2.96 RemoveSemicolon 移除分號(hào)
移除非空函數(shù)的分號(hào)。
注意,該函數(shù)可能帶來未知的風(fēng)險(xiǎn) 。
?
false: true:
int max(int a, int b) { int max(int a, int b) {
return a > b ? a : b; return a > b ? a : b;
}; }
2.97 RequiresClausePosition 要求子句位置
要求(require
)子句的位置。有以下可能的值:
OwnLine
,總是把要求子句放在單獨(dú)一行上。
?
template <typename T>
requires C<T>
struct Foo {...
template <typename T>
requires C<T>
void bar(T t) {...
template <typename T>
void baz(T t)
requires C<T>
{...
WithPreceding
,試著把從句和聲明的前面部分放在一起。
-
對(duì)于類模板:堅(jiān)持和模板聲明放在一起。
-
對(duì)于函數(shù)模板:堅(jiān)持和模板聲明放在一起。
-
對(duì)于后面跟著required子句的函數(shù)聲明:堅(jiān)持和形參列表放在一起。
template requires C
struct Foo {…template requires C
void bar(T t) {…template
void baz(T t) requires C
{…
WithFollowing
,嘗試把requires
子句和函數(shù)聲明放在一起。
?
template <typename T>
requires C<T> struct Foo {...
template <typename T>
requires C<T> void bar(T t) {...
template <typename T>
void baz(T t)
requires C<T> {...
SingleLine
如果可能的話,盡量把所有內(nèi)容放在同一行。否則正常的斷行規(guī)則就會(huì)被取代。
?
// Fitting:
template <typename T> requires C<T> struct Foo {...
template <typename T> requires C<T> void bar(T t) {...
template <typename T> void bar(T t) requires C<T> {...
// Not fitting, one possible example:
template <typename LongName>
requires C<LongName>
struct Foo {...
template <typename LongName>
requires C<LongName>
void bar(LongName ln) {
template <typename LongName>
void bar(LongName ln)
requires C<LongName> {
2.98 RequiresExpressionIndentation require
表達(dá)式縮進(jìn)
有以下選項(xiàng):
OuterScope
,相對(duì)于require表達(dá)式所在的外部范圍的縮進(jìn)級(jí)別,Align要求表達(dá)式體。這是默認(rèn)設(shè)置。
?
template <typename T>
concept C = requires(T t) {
...
}
Keyword
,Align要求相對(duì)于requires關(guān)鍵字的表達(dá)式體。
?
template <typename T>
concept C = requires(T t) {
...
}
2.99 SeparateDefinitionBlocks 分離定義語句塊
指定使用空行分隔定義塊,包括類、結(jié)構(gòu)、枚舉和函數(shù)。
?
Never v.s. Always
#include <cstring> #include <cstring>
struct Foo {
int a, b, c; struct Foo {
}; int a, b, c;
namespace Ns { };
class Bar {
public: namespace Ns {
struct Foobar { class Bar {
int a; public:
int b; struct Foobar {
}; int a;
private: int b;
int t; };
int method1() {
// ... private:
} int t;
enum List {
ITEM1, int method1() {
ITEM2 // ...
}; }
template<typename T>
int method2(T x) { enum List {
// ... ITEM1,
} ITEM2
int i, j, k; };
int method3(int par) {
// ... template<typename T>
} int method2(T x) {
}; // ...
class C {}; }
}
int i, j, k;
int method3(int par) {
// ...
}
};
class C {};
}
以下是可能的值:
-
Leave
保留原來的樣子不變。 -
Always
在定義塊之間插入空行。 -
Never
在定義塊之間移除空行。
2.100 ShortNamespaceLines 短命名空間的行數(shù)
短名稱空間所跨越的最大未換行行數(shù)。默認(rèn)值為1。
這通過計(jì)算未換行行(即既不包含開始名稱空間也不包含結(jié)束名稱空間大括號(hào))來確定短名稱空間的最大長度,并使“FixNamespaceComments
”忽略為這些名稱空間添加結(jié)束注釋。
?
ShortNamespaceLines: 1 vs. ShortNamespaceLines: 0
namespace a { namespace a {
int foo; int foo;
} } // namespace a
ShortNamespaceLines: 1 vs. ShortNamespaceLines: 0
namespace b { namespace b {
int foo; int foo;
int bar; int bar;
} // namespace b } // namespace b
2.101 SortIncludes 對(duì)inclue排序
控制clang- format
是否以及如何對(duì)#include
進(jìn)行排序。如果Never
,則包含永遠(yuǎn)不會(huì)排序。如果不區(qū)分大小寫,則以ascii
或不區(qū)分大小寫的方式對(duì)包含進(jìn)行排序。如果大小寫敏感,則包含按字母或大小寫敏感的方式排序。
以下是可能的選項(xiàng):
Never
,不對(duì)include
進(jìn)行排序。
?
#include "B/A.h"
#include "A/B.h"
#include "a/b.h"
#include "A/b.h"
#include "B/a.h"
CaseSensitive
,包含以ascii或區(qū)分大小寫的方式進(jìn)行排序。
?
#include "A/B.h"
#include "A/b.h"
#include "B/A.h"
#include "B/a.h"
#include "a/b.h"
CaseInsensitive
,包含以字母或不區(qū)分大小寫的方式排序。
?
#include "A/B.h"
#include "A/b.h"
#include "a/b.h"
#include "B/A.h"
#include "B/a.h"
2.102 SortJavaStaticImport 排序java靜態(tài)導(dǎo)入
在對(duì)Java導(dǎo)入進(jìn)行排序時(shí),默認(rèn)情況下靜態(tài)導(dǎo)入放在非靜態(tài)導(dǎo)入之前。如果JavaStaticImportAfterImport為After,則靜態(tài)導(dǎo)入放在非靜態(tài)導(dǎo)入之后。
有以下選項(xiàng):
Before
,靜態(tài)導(dǎo)入被放在非靜態(tài)導(dǎo)入前面。
?
import static org.example.function1;
import org.example.ClassA;
After
,靜態(tài)導(dǎo)入被放在非靜態(tài)導(dǎo)入前面。
?
import org.example.ClassA;
import static org.example.function1;
2.103 SortUsingDeclarations 對(duì)using聲明排序
如果為true, clang-format將使用聲明進(jìn)行排序。使用聲明的順序定義如下
用“::”分隔字符串并丟棄任何初始空字符串。每個(gè)列表的最后一個(gè)元素是非名稱空間名稱;其他的都是名稱空間名稱。按字典順序?qū)γQ列表進(jìn)行排序,先對(duì)非名稱空間名字排序,然后再對(duì)名稱空間排序。并且在這些組中,名稱按照不區(qū)分大小寫的字典順序排列。
?
false: true:
using std::cout; vs. using std::cin;
using std::cin; using std::cout;
2.104 SpaceAfterCStyleCast c風(fēng)格類型轉(zhuǎn)換
是否在c風(fēng)格的類型轉(zhuǎn)換之后插入空白符。
?
true: false:
(int) i; vs. (int)i;
2.105 SpaceAfterLogicalNot 邏輯!
操作符
是否在邏輯!
操作符后面插入空白符。
?
true: false:
! someExpression(); vs. !someExpression();
2.106 SpaceAfterTemplateKeyword 模板關(guān)鍵字
是否在模板關(guān)鍵字template
之后插入空格。
?
true: false:
template <int> void foo(); vs. template<int> void foo();
2.107 SpaceAroundPointerQualifiers 指針限定符空格
定義在何種情況下在指針限定符之前或之后放置空格
可能的情況:
Default
不用確保指針限定符周圍的空格,而是使用PointerAlignment
代替。
?
PointerAlignment: Left PointerAlignment: Right
void* const* x = NULL; vs. void *const *x = NULL;
Before
確保在指針限定符之前有一個(gè)空格。
?
PointerAlignment: Left PointerAlignment: Right
void* const* x = NULL; vs. void * const *x = NULL;
After
確保在指針限定符之后有一個(gè)空格。
?
PointerAlignment: Left PointerAlignment: Right
void* const * x = NULL; vs. void *const *x = NULL;
Both
確保在指針限定符之后和之前都有一個(gè)空格。
?
PointerAlignment: Left PointerAlignment: Right
void* const * x = NULL; vs. void *const *x = NULL;
2.108 SpaceBeforeAssignmentOperators 賦值操作符空格
如果為false,則在賦值操作符之前刪除空格。
?
true: false:
int a = 5; vs. int a= 5;
a += 42; a+= 42;
2.109 SpaceBeforeCaseColon case
前空格
如果為false,則大小寫冒號(hào)前的空格將被刪除。
?
true: false
switch (x) { vs. switch (x) {
case 1 : break; case 1: break;
} }
2.110 SpaceBeforeCpp11BracedList 大括號(hào)列表空格
如果為true,則在用于初始化對(duì)象的c++ 11大括號(hào)列表(前面的標(biāo)識(shí)符或類型之后)之前插入一個(gè)空格。
?
true: false:
Foo foo { bar }; vs. Foo foo{ bar };
Foo {}; Foo{};
vector<int> { 1, 2, 3 }; vector<int>{ 1, 2, 3 };
new int[3] { 1, 2, 3 }; new int[3]{ 1, 2, 3 };
2.111 SpaceBeforeCtorInitializerColon 構(gòu)造器初始化冒號(hào)空格
如果為false,則在構(gòu)造函數(shù)初始化式冒號(hào)之前刪除空格。
?
true: false:
Foo::Foo() : a(a) {} Foo::Foo(): a(a) {}
2.112 SpaceBeforeInheritanceColon 繼承冒號(hào)空格
如果為false,則繼承冒號(hào)前的空格將被刪除。
?
true: false:
class Foo : Bar {} vs. class Foo: Bar {}
2.113 SpaceBeforeParens 圓括號(hào)空格
定義在什么情況下在圓括號(hào)前放空格。
有以下的選項(xiàng):
Never
,從不在一個(gè)開圓括號(hào)之前放一個(gè)空格。
?
void f() {
if(true) {
f();
}
}
ControlStatement
只在控制語句關(guān)鍵字(for
/if
/while
…)之后的開括號(hào)前加空格。
?
void f() {
if (true) {
f();
}
}
ControlStatementsExceptControlMacros
和ControlStatement
類似,但是排除控制宏定義,例如ForEach
宏等。在這種情況下,ForEach
宏被當(dāng)成函數(shù)調(diào)用。
?
void f() {
Q_FOREACH(...) {
f();
}
}
NonEmptyParentheses
, 只有當(dāng)圓括號(hào)不是空的時(shí)候,才在圓括號(hào)前放空格。
?
void() {
if (true) {
f();
g (x, y, z);
}
}
Always
總是在開括號(hào)之前放一個(gè)空格,除非語法規(guī)則禁止這樣做(在函數(shù)類宏定義中),或者由其他樣式規(guī)則決定(在一元運(yùn)算符、開括號(hào)之后等)。
?
void f () {
if (true) {
f ();
}
}
Custom
在SpaceBeforeParensOptions
中獨(dú)立配置不同情況下的括號(hào)前空格。
2.114 SpaceBeforeParensOptions 圓括號(hào)前空格控制
控制括號(hào)前的個(gè)別空格。
如果SpaceBeforeParens
被設(shè)置為自定義,那么使用它來指定如何處理括號(hào)前的每個(gè)空格。否則,它將被忽略。
?
# Example of usage:
SpaceBeforeParens: Custom
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterFunctionDefinitionName: true
有以下屬性配置項(xiàng):
bool AfterControlStatements
,在控制語句for/if/while...
關(guān)鍵字和開圓括號(hào)之間放置空格。
?
true: false:
if (...) {} vs. if(...) {}
bool AfterForeachMacros
,在foreach
宏和開圓括號(hào)之間放置空格。
?
true: false:
FOREACH (...) vs. FOREACH(...)
<loop-body> <loop-body>
bool AfterFunctionDeclarationName
,在函數(shù)聲明和開圓括號(hào)之前放置空格。
?
true: false:
void f (); vs. void f();
bool AfterFunctionDefinitionName
,在函數(shù)定義名稱和左括號(hào)之間用空格隔開。
?
true: false:
void f () {} vs. void f() {}
bool AfterIfMacros
,在if宏和左括號(hào)之間放空格。
?
true: false:
IF (...) vs. IF(...)
<conditional-body> <conditional-body>
bool AfterOverloadedOperator
,在操作符重載和開括號(hào)之間放一個(gè)空格。
?
true: false:
void operator++ (int a); vs. void operator++(int a);
object.operator++ (10); object.operator++(10);
bool AfterRequiresInClause
,在required子句中的required關(guān)鍵字和開括號(hào)(如果有的話)之間放空格。
?
true: false:
template<typename T> vs. template<typename T>
requires (A<T> && B<T>) requires(A<T> && B<T>)
...
bool AfterRequiresInExpression
,在required表達(dá)式中的required關(guān)鍵字和開括號(hào)之間放空格。
?
true: false:
template<typename T> vs. template<typename T>
concept C = requires (T t) { concept C = requires(T t) {
... ...
} }
bool BeforeNonEmptyParentheses
,只有當(dāng)圓括號(hào)不是空的時(shí)候,才在圓括號(hào)前放空格。
?
true: false:
void f (int a); vs. void f();
f (a); f();
2.115 SpaceBeforeRangeBasedForLoopColon 循環(huán)范圍里的冒號(hào)
如果為false,則在基于范圍的for循環(huán)冒號(hào)之前刪除空格。
?
true: false:
for (auto v : values) {} vs. for(auto v: values) {}
2.116 SpaceBeforeSquareBrackets 方括號(hào)前空格
如果為true,空格將在[
之前。Lambdas不會(huì)受到影響。只有第一個(gè)[
會(huì)被添加一個(gè)空格。
?
true: false:
int a [5]; vs. int a[5];
int a [5][5]; vs. int a[5][5];
2.117 SpaceInEmptyBlock 空塊中的空格
如果為true,將在{}中插入空格。
?
true: false:
void f() { } vs. void f() {}
while (true) { } while (true) {}
2.118 SpaceInEmptyParentheses 圓括號(hào)之間的空格
如果為true,則可以在()中插入空格。
?
true: false:
void f( ) { vs. void f() {
int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()};
if (true) { if (true) {
f( ); f();
} }
} }
2.119 SpacesBeforeTrailingComments 尾部注釋之前的空格
尾隨行注釋前的空格數(shù)(//
- comments)。
這并不影響尾隨塊注釋(/*
-注釋),因?yàn)樗鼈兺ǔ>哂胁煌氖褂媚J胶驮S多特殊情況。
?
SpacesBeforeTrailingComments: 3
void f() {
if (true) { // foo1
f(); // bar
} // foo
}
2.120 SpacesInAngles 角括號(hào)空白
用于模板參數(shù)列表的SpacesInAnglesStyle。
Never
,刪除<
和>
之前的空格。
?
static_cast<int>(arg);
std::function<void(int)> fct;
ALways
,在<
和>
之間增加空白符。
?
static_cast< int >(arg);
std::function< void(int) > fct;
Leave
,如果有空格,則在<
之后和>
之前保留一個(gè)空格。選項(xiàng)Standard:Cpp03
優(yōu)先。
2.121 SpacesInCStyleCastParentheses Ccast
轉(zhuǎn)換里的空格
如果為true,空格可以插入到C樣式強(qiáng)制轉(zhuǎn)換中。
?
true: false:
x = ( int32 )y vs. x = (int32)y
2.122 SpacesInConditionalStatement 條件表達(dá)式中的空白
如果為true,將在If /for/switch/while條件周圍插入空格。
?
true: false:
if ( a ) { ... } vs. if (a) { ... }
while ( i < 5 ) { ... } while (i < 5) { ... }
2.123 SpacesInContainerLiterals 容器中空格
如果為true,則在容器字面量中插入空格(例如ObjC
和Javascript
數(shù)組和dict
字面量)。
?
true: false:
var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3});
2.124 SpacesInLineCommentPrefix 行注釋前綴空格
行注釋的開頭允許有多少空格。要禁用最大值,請(qǐng)將其設(shè)置為-1
,除此之外,最大值優(yōu)先于最小值。
?
Minimum = 1
Maximum = -1
// One space is forced
// but more spaces are possible
Minimum = 0
Maximum = 0
//Forces to start every comment directly after the slashes
注意,在行注釋區(qū)中,后面的行保持相對(duì)縮進(jìn),這意味著:
?
before: after:
Minimum: 1
//if (b) { // if (b) {
// return true; // return true;
//} // }
Maximum: 0
/// List: ///List:
/// - Foo /// - Foo
/// - Bar /// - Bar
2.125 SpacesInParentheses 在圓括號(hào)里面的空格
如果為true,則在后面(和前面)插入空格。
?
true: false:
t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete;
2.126 SpacesInSquareBrackets 方括號(hào)之中的空白
如果為true,則在[
和]
之前插入空格。沒有參數(shù)或未指定大小的數(shù)組聲明的Lambdas
不會(huì)受到影響。
?
true: false:
int a[ 5 ]; vs. int a[5];
std::unique_ptr<int[]> foo() {} // Won't be affected
2.127 Standard C++標(biāo)準(zhǔn)
解析和格式化與此標(biāo)準(zhǔn)兼容的c++結(jié)構(gòu)。
?
c++03: latest:
vector<set<int> > x; vs. vector<set<int>> x;
可能的情況:
c++03
,解析和格式化為c++03
。Cpp03
是c++03
已棄用的別名
c++11
,解析和格式化為c++11
。
c++14
,解析和格式化為c++14
。
c++17
,解析和格式化為c++17
。
c++20
,解析和格式化為c++20
。
Latest
,解析和格式化為最新的支持版本。
Auto
,根據(jù)輸入和輸出自動(dòng)檢測語言。
2.128 StatementAttributeLikeMacros
在語句前面被忽略的宏,就像它們是一個(gè)屬性一樣。這樣它們就不會(huì)被解析為標(biāo)識(shí)符,例如Qts的發(fā)出。
?
AlignConsecutiveDeclarations: true
StatementAttributeLikeMacros: []
unsigned char data = 'x';
emit signal(data); // This is parsed as variable declaration.
AlignConsecutiveDeclarations: true
StatementAttributeLikeMacros: [emit]
unsigned char data = 'x';
emit signal(data); // Now it's fine again.
2.129 StatementMacros
應(yīng)該被解釋為完整語句的宏向量。
典型的宏是表達(dá)式,需要添加分號(hào); 有時(shí)情況并非如此,這允許clang-format意識(shí)到這種情況。
?
StatementMacros:["Stack",...]
2.130 TabWidth Tab的寬度,替換為空白字符
2.131 TypenameMacros 類型名宏定義
應(yīng)該被解釋為類型聲明而不是函數(shù)調(diào)用的宏向量。
?
STACK_OF(...)
.clang-format
,可以被配置如下。
?
TypenameMacros: ['STACK_OF', 'LIST']
2.132 UseCRLF 換行符種類
換行時(shí)使用\r\n
而不是\n
。如果DeriveLineEnding
為真,也可用作回退。
2.133 UseTab Tab的使用
在結(jié)果文件中使用制表符的方法。
可能的值:
Never
,從不使用tab
。
ForIndentation
,僅用于縮進(jìn)。
ForContinuationAndIndentation
,用制表符填充所有前導(dǎo)空白,并使用空格對(duì)齊出現(xiàn)在一行內(nèi)(例如連續(xù)賦值和聲明)。
AlignWithSpaces
,使用制表符進(jìn)行行繼續(xù)和縮進(jìn),使用空格進(jìn)行對(duì)齊。
Always
,每當(dāng)需要填充至少跨越一個(gè)制表位到下一個(gè)制表位的空白時(shí),就使用制表符。
2.134 WhitespaceSensitiveMacros
對(duì)空白敏感且不應(yīng)被觸及的宏向量。這些被期望為如下形式的宏:
?
STRINGIZE(...)
WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE']
4. 結(jié)束語
格式工整的代碼是每個(gè)programmer應(yīng)該追求的。這里提供一版我配置好的規(guī)則。文章來源:http://www.zghlxwxcb.cn/news/detail-445098.html
Windows端:windows端clang-format,復(fù)制粘貼即可
Linux端: Linux端clang-format,復(fù)制粘貼即可文章來源地址http://www.zghlxwxcb.cn/news/detail-445098.html
到了這里,關(guān)于【C++】Clang-Format:代碼自動(dòng)格式化(看這一篇就夠了)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!