Clang-Format 样式选项

Clang-Format 样式选项 描述了 LibFormatClangFormat 支持的可配置格式化样式选项。

在使用 clang-format 命令行工具或代码中的 clang::format::reformat(...) 函数时,您可以使用预定义的样式之一(LLVM、Google、Chromium、Mozilla、WebKit、Microsoft),也可以通过配置特定的样式选项来创建自定义样式。

使用 clang-format 配置样式

clang-format 支持两种方式来提供自定义样式选项:直接在 -style= 命令行选项中指定样式配置,或使用 -style=file 并将样式配置放在项目目录中的 .clang-format_clang-format 文件中。

当使用 -style=file 时,clang-format 会为每个输入文件尝试找到位于输入文件最近的父目录中的 .clang-format 文件。当使用标准输入时,搜索将从当前目录开始。

当使用 -style=file:<format_file_path> 时,clang-format 将为每个输入文件使用位于 <format_file_path> 的格式文件。该路径可以是绝对路径或相对于工作目录的路径。

.clang-format 文件使用 YAML 格式

key1: value1
key2: value2
# A comment.
...

配置文件可以包含多个部分,每个部分都有不同的 Language: 参数,表示该部分配置的目标编程语言。有关支持的语言列表,请参见下面 Language 选项的描述。第一个部分可能没有设置语言,它将为所有语言设置默认样式选项。针对特定语言的配置部分将覆盖在默认部分中设置的选项。

clang-format 格式化文件时,它会使用文件名自动检测语言。当格式化标准输入或没有与其语言相对应的扩展名的文件时,可以使用 -assume-filename= 选项来覆盖 clang-format 用于检测语言的文件名。

多个语言的配置文件示例

---
# 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
...

获取包含特定预定义样式的所有配置选项的有效 .clang-format 文件的一种简单方法是

clang-format -style=llvm -dump-config > .clang-format

-style= 选项中指定配置时,相同的配置将应用于所有输入文件。配置的格式为

-style='{key1: value1, key2: value2, ...}'

禁用代码片段的格式化

Clang-format 还理解用于切换定界范围内格式化的特殊注释。注释 // clang-format off/* clang-format off */ 到注释 // clang-format on/* clang-format on */ 之间的代码将不会被格式化。注释本身将按正常方式格式化(对齐)。此外,冒号 (:) 和其他文本可以跟随 // clang-format off// clang-format on 来解释为什么 clang-format 被关闭或重新打开。

int formatted_code;
// clang-format off
    void    unformatted_code  ;
// clang-format on
void formatted_code_again;

在代码中配置样式

当使用 clang::format::reformat(...) 函数时,格式通过提供 clang::format::FormatStyle 结构来指定。

可配置的格式样式选项

本节列出了支持的样式选项。每个选项都指定了值类型。对于枚举类型,可能的枚举值将以 C++ 枚举成员的形式指定(带有前缀,例如 LS_Auto),以及在配置中可用的值(不带前缀:Auto)。

BasedOnStyle (String)

用于所有未在配置中明确设置的选项的样式。

此选项仅在 clang-format 配置中支持(在 -style='{...}'.clang-format 文件中)。

可能的值

AccessModifierOffset (Integer) clang-format 3.3

访问修饰符(例如 public:)的额外缩进或缩进。

AlignAfterOpenBracket (BracketAlignmentStyle) clang-format 3.8

如果为 true,则在打开的括号后水平对齐参数。

这适用于圆括号(圆括号)、尖括号和方括号。

可能的值

  • BAS_Align (在配置中:Align) 在打开的括号上对齐参数,例如

    someLongFunction(argument1,
                     argument2);
    
  • BAS_DontAlign (在配置中:DontAlign) 不要对齐,而是使用 ContinuationIndentWidth,例如

    someLongFunction(argument1,
        argument2);
    
  • BAS_AlwaysBreak (在配置中:AlwaysBreak) 如果参数不能在一行上放,则始终在打开的括号后换行,例如

    someLongFunction(
        argument1, argument2);
    
  • BAS_BlockIndent (在配置中:BlockIndent) 如果参数不能在一行上放,则始终在打开的括号后换行。关闭括号将放在新的一行。例如

    someLongFunction(
        argument1, argument2
    )
    

    注意

    这目前仅适用于大括号初始化列表(当 Cpp11BracedListStyletrue)和圆括号。

AlignArrayOfStructures (ArrayInitializerAlignmentStyle) clang-format 13

如果非 None,则在使用结构体数组的初始化时,会将字段对齐成列。

注意

从 clang-format 15 开始,此选项仅适用于每行列数相同的数组。

可能的值

  • AIAS_Left (在配置中:Left) 对齐数组列并左对齐列,例如

    struct test demo[] =
    {
        {56, 23,    "hello"},
        {-1, 93463, "world"},
        {7,  5,     "!!"   }
    };
    
  • AIAS_Right (在配置中:Right) 对齐数组列并右对齐列,例如

    struct test demo[] =
    {
        {56,    23, "hello"},
        {-1, 93463, "world"},
        { 7,     5,    "!!"}
    };
    
  • AIAS_None (在配置中:None) 不要对齐数组初始化列表的列。

AlignConsecutiveAssignments (AlignConsecutiveStyle) clang-format 3.8

对齐连续赋值的样式。

Consecutive 将导致像这样的格式化

int a            = 1;
int somelongname = 2;
double c         = 3;

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveAssignments: AcrossEmptyLines

AlignConsecutiveAssignments:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveBitFields (AlignConsecutiveStyle) clang-format 11

对齐连续位域的样式。

Consecutive 将对齐连续行的位域分隔符。 这将导致以下格式:

int aaaa : 1;
int b    : 12;
int ccc  : 8;

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveBitFields: AcrossEmptyLines

AlignConsecutiveBitFields:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveDeclarations (AlignConsecutiveStyle) clang-format 3.8

对齐连续声明的样式。

Consecutive 将对齐连续行的声明名称。 这将导致以下格式:

int         aaaa = 12;
float       b = 23;
std::string ccc;

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveDeclarations: AcrossEmptyLines

AlignConsecutiveDeclarations:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveMacros (AlignConsecutiveStyle) clang-format 9

对齐连续宏定义的样式。

Consecutive 将导致像这样的格式化

#define SHORT_NAME       42
#define LONGER_NAME      0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x)           (x * x)
#define bar(y, z)        (y + z)

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveMacros: AcrossEmptyLines

AlignConsecutiveMacros:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveShortCaseStatements (ShortCaseStatementsAlignmentStyle) clang-format 17

对齐连续短 case 标签的样式。 仅在 AllowShortCaseExpressionOnASingleLineAllowShortCaseLabelsOnASingleLinetrue 时适用。

# Example of usage:
AlignConsecutiveShortCaseStatements:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: true
  AlignCaseColons: false

嵌套配置标志

对齐选项。

  • bool Enabled 是否启用对齐。

    true:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    default:           return "";
    }
    
    false:
    switch (level) {
    case log::info: return "info:";
    case log::warning: return "warning:";
    default: return "";
    }
    
  • bool AcrossEmptyLines 是否跨越空行对齐。

    true:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    
    default:           return "";
    }
    
    false:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    
    default: return "";
    }
    
  • bool AcrossComments 是否跨越注释对齐。

    true:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    /* A comment. */
    default:           return "";
    }
    
    false:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    /* A comment. */
    default: return "";
    }
    
  • bool AlignCaseArrows 是否在对齐短 case 表达式时对齐 case 箭头。

    true:
    i = switch (day) {
      case THURSDAY, SATURDAY -> 8;
      case WEDNESDAY          -> 9;
      default                 -> 0;
    };
    
    false:
    i = switch (day) {
      case THURSDAY, SATURDAY -> 8;
      case WEDNESDAY ->          9;
      default ->                 0;
    };
    
  • bool AlignCaseColons 是否在冒号上对齐对齐的 case 标签,还是在冒号后的标记上对齐。

    true:
    switch (level) {
    case log::info   : return "info:";
    case log::warning: return "warning:";
    default          : return "";
    }
    
    false:
    switch (level) {
    case log::info:    return "info:";
    case log::warning: return "warning:";
    default:           return "";
    }
    
AlignConsecutiveTableGenBreakingDAGArgColons (AlignConsecutiveStyle) clang-format 19

对齐连续 TableGen DAGArg 运算符冒号的样式。 如果启用,则对齐 DAGArg 内部的冒号,这些冒号在 DAGArg 内有换行符。 这仅在 TableGenBreakInsideDAGArg 为 BreakElements 或 BreakAll 且 DAGArg 未被 TableGenBreakingDAGArgOperators 的效果排除时有效。

let dagarg = (ins
    a  :$src1,
    aa :$src2,
    aaa:$src3
)

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveTableGenBreakingDAGArgColons: AcrossEmptyLines

AlignConsecutiveTableGenBreakingDAGArgColons:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveTableGenCondOperatorColons (AlignConsecutiveStyle) clang-format 19

对齐连续 TableGen 条件运算符冒号的样式。 对齐 !cond 运算符内部情况的冒号。

!cond(!eq(size, 1) : 1,
      !eq(size, 16): 1,
      true         : 0)

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveTableGenCondOperatorColons: AcrossEmptyLines

AlignConsecutiveTableGenCondOperatorColons:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignConsecutiveTableGenDefinitionColons (AlignConsecutiveStyle) clang-format 19

对齐连续 TableGen 定义冒号的样式。 这将对齐连续定义的继承冒号。

def Def       : Parent {}
def DefDef    : Parent {}
def DefDefDef : Parent {}

嵌套配置标志

对齐选项。

它们也可以作为整体读取以实现兼容性。选择有

  • None

  • Consecutive

  • AcrossEmptyLines

  • AcrossComments

  • AcrossEmptyLinesAndComments

例如,要跨越空行对齐,而不要跨越注释对齐,则可以使用以下两种方式。

AlignConsecutiveTableGenDefinitionColons: AcrossEmptyLines

AlignConsecutiveTableGenDefinitionColons:
  Enabled: true
  AcrossEmptyLines: true
  AcrossComments: false
  • bool Enabled 是否启用对齐。

    #define SHORT_NAME       42
    #define LONGER_NAME      0x007f
    #define EVEN_LONGER_NAME (2)
    #define foo(x)           (x * x)
    #define bar(y, z)        (y + z)
    
    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 是否跨越空行对齐。

    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 是否跨越注释对齐。

    true:
    int d    = 3;
    /* A comment. */
    double e = 4;
    
    false:
    int d = 3;
    /* A comment. */
    double e = 4;
    
  • bool AlignCompound 仅适用于 AlignConsecutiveAssignments。 是否将复合赋值(如 +=)与 = 一起对齐。

    true:
    a   &= 2;
    bbb  = 2;
    
    false:
    a &= 2;
    bbb = 2;
    
  • bool AlignFunctionDeclarations 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数声明。

    true:
    unsigned int f1(void);
    void         f2(void);
    size_t       f3(void);
    
    false:
    unsigned int f1(void);
    void f2(void);
    size_t f3(void);
    
  • bool AlignFunctionPointers 仅适用于 AlignConsecutiveDeclarations。 是否对齐函数指针。

    true:
    unsigned i;
    int     &r;
    int     *p;
    int      (*f)();
    
    false:
    unsigned i;
    int     &r;
    int     *p;
    int (*f)();
    
  • bool PadOperators 仅适用于 AlignConsecutiveAssignments。 是否将短赋值运算符左填充到与长运算符相同的长度,以便将所有赋值运算符放在左侧的右边。

    true:
    a   >>= 2;
    bbb   = 2;
    
    a     = 2;
    bbb >>= 2;
    
    false:
    a >>= 2;
    bbb = 2;
    
    a     = 2;
    bbb >>= 2;
    
AlignEscapedNewlines (EscapedNewlineAlignmentStyle) clang-format 5

对齐转义换行符中的反斜杠的选项。

可能的值

  • ENAS_DontAlign (在配置中: DontAlign) 不要对齐转义换行符。

    #define A \
      int aaaa; \
      int b; \
      int dddddddddd;
    
  • ENAS_Left (在配置中: Left) 将转义换行符尽可能靠左对齐。

    #define A   \
      int aaaa; \
      int b;    \
      int dddddddddd;
    
  • ENAS_LeftWithLastLine (在配置中: LeftWithLastLine) 将转义换行符尽可能靠左对齐,如果预处理器指令的最后一行是最长的,则使用最后一行作为参考。

    #define A         \
      int aaaa;       \
      int b;          \
      int dddddddddd;
    
  • ENAS_Right (在配置中: Right) 将转义换行符在最右边一列对齐。

    #define A                                                                      \
      int aaaa;                                                                    \
      int b;                                                                       \
      int dddddddddd;
    
AlignOperands (OperandAlignmentStyle) clang-format 3.5

如果 true,则水平对齐二元和三元表达式的操作数。

可能的值

  • OAS_DontAlign (在配置中: DontAlign) 不要对齐二元和三元表达式的操作数。 包装行从行首缩进 ContinuationIndentWidth 个空格。

  • OAS_Align (在配置中: Align) 水平对齐二元和三元表达式的操作数。

    具体来说,这将对齐需要拆分为多行的单个表达式的操作数,例如:

    int aaa = bbbbbbbbbbbbbbb +
              ccccccccccccccc;
    

    BreakBeforeBinaryOperators 设置时,包装的运算符与第一行上的操作数对齐。

    int aaa = bbbbbbbbbbbbbbb
              + ccccccccccccccc;
    
  • OAS_AlignAfterOperator (在配置中: AlignAfterOperator) 水平对齐二元和三元表达式的操作数。

    这类似于 OAS_Align,只是当 BreakBeforeBinaryOperators 设置时,运算符将取消缩进,以便包装的操作数与第一行上的操作数对齐。

    int aaa = bbbbbbbbbbbbbbb
            + ccccccccccccccc;
    
AlignTrailingComments (TrailingCommentsAlignmentStyle) clang-format 3.7

尾部注释的控制。

对齐在换行符后的闭合大括号处停止,并且仅在后面紧跟着其他闭合大括号、(do-while、lambda 调用或分号的情况下停止。

注意

从 clang-format 16 开始,此选项不是布尔值,而是可以设置为选项。 传统的布尔值选项仍然可以像以前一样解析。

# Example of usage:
AlignTrailingComments:
  Kind: Always
  OverEmptyLines: 2

嵌套配置标志

对齐选项

  • TrailingCommentsAlignmentKinds Kind 指定对齐尾部注释的方式。

    可能的值

    • TCAS_Leave (在配置中: Leave) 保留尾部注释的原样。

      int a;    // comment
      int ab;       // comment
      
      int abc;  // comment
      int abcd;     // comment
      
    • TCAS_Always (在配置中: Always) 对齐尾部注释。

      int a;  // comment
      int ab; // comment
      
      int abc;  // comment
      int abcd; // comment
      
    • TCAS_Never (在配置中: Never) 不要对齐尾部注释,但其他格式化程序会应用。

      int a; // comment
      int ab; // comment
      
      int abc; // comment
      int abcd; // comment
      
  • unsigned OverEmptyLines 应用对齐的空行数。 当 MaxEmptyLinesToKeepOverEmptyLines 都设置为 2 时,它会像下面这样格式化。

    int a;      // all these
    
    int ab;     // comments are
    
    
    int abcdef; // aligned
    

    MaxEmptyLinesToKeep 设置为 2 且 OverEmptyLines 设置为 1 时,它会像下面这样格式化。

    int a;  // these are
    
    int ab; // aligned
    
    
    int abcdef; // but this isn't
    
AllowAllArgumentsOnNextLine (Boolean) clang-format 9

如果函数调用或花括号初始化列表不适合一行,则允许将所有参数放到下一行,即使 BinPackArgumentsfalse

true:
callFunction(
    a, b, c, d);

false:
callFunction(a,
             b,
             c,
             d);
AllowAllConstructorInitializersOnNextLine (Boolean) clang-format 9

此选项已**弃用**。 请参阅 PackConstructorInitializersNextLine

AllowAllParametersOfDeclarationOnNextLine (Boolean) clang-format 3.3

如果函数声明不适合一行,则允许将函数声明的所有参数放到下一行,即使 BinPackParametersOnePerLine

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);
AllowBreakBeforeNoexceptSpecifier (BreakBeforeNoexceptSpecifierStyle) clang-format 18

控制是否可以在 noexcept 说明符之前换行。

可能的值

  • BBNSS_Never (在配置中: Never) 不允许换行。

    void foo(int arg1,
             double arg2) noexcept;
    
    void bar(int arg1, double arg2) noexcept(
        noexcept(baz(arg1)) &&
        noexcept(baz(arg2)));
    
  • BBNSS_OnlyWithParen (在配置中: OnlyWithParen) 对于简单的 noexcept,不允许换行,但是当我们有条件时,则允许换行。

    void foo(int arg1,
             double arg2) noexcept;
    
    void bar(int arg1, double arg2)
        noexcept(noexcept(baz(arg1)) &&
                 noexcept(baz(arg2)));
    
  • BBNSS_Always (在配置中: Always) 允许换行。 但请注意,由于相关的惩罚,clang-format 通常更喜欢不在 noexcept 之前换行。

    void foo(int arg1,
             double arg2) noexcept;
    
    void bar(int arg1, double arg2)
        noexcept(noexcept(baz(arg1)) &&
                 noexcept(baz(arg2)));
    
AllowShortBlocksOnASingleLine (ShortBlockStyle) clang-format 3.5

取决于值,while (true) { continue; } 可以放在一行上。

可能的值

  • SBS_Never(在配置中:Never)从不将块合并到一行。

    while (true) {
    }
    while (true) {
      continue;
    }
    
  • SBS_Empty(在配置中:Empty)仅合并空块。

    while (true) {}
    while (true) {
      continue;
    }
    
  • SBS_Always(在配置中:Always)始终将短块合并到一行。

    while (true) {}
    while (true) { continue; }
    
AllowShortCaseExpressionOnASingleLine (Boolean) clang-format 19

是否将一个短的 switch 标签规则合并到一行。

true:                               false:
switch (a) {           vs.          switch (a) {
case 1 -> 1;                        case 1 ->
default -> 0;                         1;
};                                  default ->
                                      0;
                                    };
AllowShortCaseLabelsOnASingleLine (Boolean) clang-format 3.6

如果为 true,则会将短 case 标签缩减为一行。

true:                                   false:
switch (a) {                    vs.     switch (a) {
case 1: x = 1; break;                   case 1:
case 2: return;                           x = 1;
}                                         break;
                                        case 2:
                                          return;
                                        }
AllowShortCompoundRequirementOnASingleLine (Boolean) clang-format 18

允许将短的复合要求放在一行上。

true:
template <typename T>
concept c = requires(T x) {
  { x + 1 } -> std::same_as<int>;
};

false:
template <typename T>
concept c = requires(T x) {
  {
    x + 1
  } -> std::same_as<int>;
};
AllowShortEnumsOnASingleLine (Boolean) clang-format 11

允许将短枚举放在一行上。

true:
enum { A, B } myEnum;

false:
enum {
  A,
  B
} myEnum;
AllowShortFunctionsOnASingleLine (ShortFunctionStyle) clang-format 3.5

取决于值,int f() { return 0; } 可以放在一行上。

可能的值

  • SFS_None(在配置中:None)从不将函数合并到一行。

  • SFS_InlineOnly(在配置中:InlineOnly)仅合并在类内定义的函数。与 inline 相同,但它并不意味着 empty:即顶层空函数也不会被合并。

    class Foo {
      void f() { foo(); }
    };
    void f() {
      foo();
    }
    void f() {
    }
    
  • SFS_Empty(在配置中:Empty)仅合并空函数。

    void f() {}
    void f2() {
      bar2();
    }
    
  • SFS_Inline(在配置中:Inline)仅合并在类内定义的函数。意味着 empty

    class Foo {
      void f() { foo(); }
    };
    void f() {
      foo();
    }
    void f() {}
    
  • SFS_All(在配置中:All)合并所有适合放在一行上的函数。

    class Foo {
      void f() { foo(); }
    };
    void f() { bar(); }
    
AllowShortIfStatementsOnASingleLine (ShortIfStyle) clang-format 3.3

取决于值,if (a) return; 可以放在一行上。

可能的值

  • SIS_Never(在配置中:Never)从不将短 if 语句放在同一行。

    if (a)
      return;
    
    if (b)
      return;
    else
      return;
    
    if (c)
      return;
    else {
      return;
    }
    
  • SIS_WithoutElse(在配置中:WithoutElse)仅当没有 else 语句时,才将短 if 语句放在同一行。

    if (a) return;
    
    if (b)
      return;
    else
      return;
    
    if (c)
      return;
    else {
      return;
    }
    
  • SIS_OnlyFirstIf(在配置中:OnlyFirstIf)将短 if 语句(但不是 else if 以及 else 语句)放在同一行。

    if (a) return;
    
    if (b) return;
    else if (b)
      return;
    else
      return;
    
    if (c) return;
    else {
      return;
    }
    
  • SIS_AllIfsAndElse(在配置中:AllIfsAndElse)始终将短 if 语句、else if 语句和 else 语句放在同一行。

    if (a) return;
    
    if (b) return;
    else return;
    
    if (c) return;
    else {
      return;
    }
    
AllowShortLambdasOnASingleLine (ShortLambdaStyle) clang-format 9

取决于值,auto lambda []() { return 0; } 可以放在一行上。

可能的值

  • SLS_None(在配置中:None)从不将 lambda 合并到一行。

  • SLS_Empty(在配置中:Empty)仅合并空 lambda。

    auto lambda = [](int a) {};
    auto lambda2 = [](int a) {
        return a;
    };
    
  • SLS_Inline(在配置中:Inline)如果 lambda 是函数的参数,则将其合并到一行。

    auto lambda = [](int x, int y) {
        return x < y;
    };
    sort(a.begin(), a.end(), [](int x, int y) { return x < y; });
    
  • SLS_All(在配置中:All)合并所有适合放在一行上的 lambda。

    auto lambda = [](int a) {};
    auto lambda2 = [](int a) { return a; };
    
AllowShortLoopsOnASingleLine (Boolean) clang-format 3.7

如果为 true,则 while (true) continue; 可以放在一行上。

AlwaysBreakAfterDefinitionReturnType (DefinitionReturnTypeBreakingStyle) clang-format 3.7

要使用的函数定义返回类型断行样式。此选项已 **弃用**,保留用于向后兼容性。

可能的值

  • DRTBS_None(在配置中:None)自动在返回类型后断行。将考虑 PenaltyReturnTypeOnItsOwnLine

  • DRTBS_All(在配置中:All)始终在返回类型后断行。

  • DRTBS_TopLevel(在配置中:TopLevel)始终在顶层函数的返回类型后断行。

AlwaysBreakAfterReturnType (deprecated) clang-format 3.8

此选项已重命名为 BreakAfterReturnType

AlwaysBreakBeforeMultilineStrings (Boolean) clang-format 3.4

如果为 true,则始终在多行字符串文字之前断行。

此标志旨在使文件中存在多个多行字符串的情况看起来更加一致。因此,只有在该点换行会导致字符串从行首缩进 ContinuationIndentWidth 个空格时,它才会生效。

true:                                  false:
aaaa =                         vs.     aaaa = "bbbb"
    "bbbb"                                    "cccc";
    "cccc";
AlwaysBreakTemplateDeclarations (deprecated) clang-format 3.4

此选项已重命名为 BreakTemplateDeclarations

AttributeMacros (List of Strings) clang-format 12

一个字符串向量,应该被解释为属性/限定符而不是标识符。这对于语言扩展或静态分析器注释很有用。

例如

x = (char *__capability)&y;
int function(void) __unused;
void only_writes_to_buffer(char *__output buffer);

在 .clang-format 配置文件中,可以像这样配置它

AttributeMacros: [__capability, __output, __unused]
BinPackArguments (Boolean) clang-format 3.7

如果为 false,则函数调用的参数将全部位于同一行,或者每个参数将占一行。

true:
void f() {
  f(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa,
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}

false:
void f() {
  f(aaaaaaaaaaaaaaaaaaaa,
    aaaaaaaaaaaaaaaaaaaa,
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
}
BinPackParameters (BinPackParametersStyle) clang-format 3.7

要使用的 bin pack 参数样式。

可能的值

  • BPPS_BinPack(在配置中:BinPack)按 bin 打包参数。

    void f(int a, int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
           int ccccccccccccccccccccccccccccccccccccccccccc);
    
  • BPPS_OnePerLine(在配置中:OnePerLine)如果参数适合当前行,则将所有参数放在当前行。否则,将每个参数放在单独的行上。

    void f(int a, int b, int c);
    
    void f(int a,
           int b,
           int ccccccccccccccccccccccccccccccccccccc);
    
  • BPPS_AlwaysOnePerLine(在配置中:AlwaysOnePerLine)始终将每个参数放在单独的行上。

    void f(int a,
           int b,
           int c);
    
BitFieldColonSpacing (BitFieldColonSpacingStyle) clang-format 12

要用于位字段的 BitFieldColonSpacingStyle。

可能的值

  • BFCS_Both(在配置中:Both)在 : 两侧添加一个空格

    unsigned bf : 2;
    
  • BFCS_None(在配置中:None)在 : 附近不添加空格(除非 AlignConsecutiveBitFields 需要)。

    unsigned bf:2;
    
  • BFCS_Before(在配置中:Before)仅在 : 之前添加空格

    unsigned bf :2;
    
  • BFCS_After(在配置中:After)仅在 : 后添加空格(如果 AlignConsecutiveBitFields 需要,则可以在之前添加空格)。

    unsigned bf: 2;
    
BraceWrapping (BraceWrappingFlags) clang-format 3.8

控制单个大括号包裹情况。

如果 BreakBeforeBraces 设置为 Custom,则使用此选项指定每个单个大括号情况应如何处理。否则,此选项将被忽略。

# Example of usage:
BreakBeforeBraces: Custom
BraceWrapping:
  AfterEnum: true
  AfterStruct: false
  SplitEmptyFunction: false

嵌套配置标志

精确控制大括号的包裹方式。

# Should be declared this way:
BreakBeforeBraces: Custom
BraceWrapping:
    AfterClass: true
  • bool AfterCaseLabel 包裹 case 标签。

    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 {};
    
  • BraceWrappingAfterControlStatementStyle AfterControlStatement 包裹控制语句 (if/for/while/switch/..)。

    可能的值

    • BWACS_Never (在配置中:Never) 从不包裹控制语句之后的大括号。

      if (foo()) {
      } else {
      }
      for (int i = 0; i < 10; ++i) {
      }
      
    • BWACS_MultiLine (在配置中:MultiLine) 仅包裹多行控制语句之后的大括号。

      if (foo && bar &&
          baz)
      {
        quux();
      }
      while (foo || bar) {
      }
      
    • BWACS_Always (在配置中:Always) 始终包裹控制语句之后的大括号。

      if (foo())
      {
      } else
      {}
      for (int i = 0; i < 10; ++i)
      {}
      
  • bool AfterEnum 包裹枚举定义。

    true:
    enum X : int
    {
      B
    };
    
    false:
    enum X : int { B };
    
  • bool AfterFunction 包裹函数定义。

    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 包裹 Objective-C 定义(接口、实现等)。

    注意

    @autoreleasepool 和 @synchronized 块根据 AfterControlStatement 标志进行包裹。

  • bool AfterStruct 包裹结构体定义。

    true:
    struct foo
    {
      int x;
    };
    
    false:
    struct foo {
      int x;
    };
    
  • bool AfterUnion 包裹联合体定义。

    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 块。

    true:
    connect(
      []()
      {
        foo();
        bar();
      });
    
    false:
    connect([]() {
      foo();
      bar();
    });
    
  • bool BeforeWhile 包裹 while 之前的部分。

    true:
    do {
      foo();
    }
    while (1);
    
    false:
    do {
      foo();
    } while (1);
    
  • bool IndentBraces 缩进包裹的大括号本身。

  • bool SplitEmptyFunction 如果为 false,则可以将空函数体放在单行上。此选项仅在函数的起始大括号已被包裹时使用,即 AfterFunction 大括号包裹模式已设置,并且函数不能/不应该放在单行上(根据 AllowShortFunctionsOnASingleLine 和构造函数格式选项)。

    false:          true:
    int f()   vs.   int f()
    {}              {
                    }
    
  • bool SplitEmptyRecord 如果为 false,则可以将空记录(例如类、结构体或联合体)体放在单行上。此选项仅在记录的起始大括号已被包裹时使用,即 AfterClass(对于类)大括号包裹模式已设置。

    false:           true:
    class Foo   vs.  class Foo
    {}               {
                     }
    
  • bool SplitEmptyNamespace 如果为 false,则可以将空命名空间体放在单行上。此选项仅在命名空间的起始大括号已被包裹时使用,即 AfterNamespace 大括号包裹模式已设置。

    false:               true:
    namespace Foo   vs.  namespace Foo
    {}                   {
                         }
    
BracedInitializerIndentWidth (Unsigned) clang-format 17

用于缩进大括号初始化列表内容的列数。如果未设置,则使用 ContinuationIndentWidth

AlignAfterOpenBracket: AlwaysBreak
BracedInitializerIndentWidth: 2

void f() {
  SomeClass c{
    "foo",
    "bar",
    "baz",
  };
  auto s = SomeStruct{
    .foo = "foo",
    .bar = "bar",
    .baz = "baz",
  };
  SomeArrayT a[3] = {
    {
      foo,
      bar,
    },
    {
      foo,
      bar,
    },
    SomeArrayT{},
  };
}
BreakAdjacentStringLiterals (Boolean) clang-format 18

在相邻的字符串文字之间添加换行。

true:
return "Code"
       "\0\52\26\55\55\0"
       "x013"
       "\02\xBA";
false:
return "Code" "\0\52\26\55\55\0" "x013" "\02\xBA";
BreakAfterAttributes (AttributeBreakingStyle) clang-format 16

在变量或函数(包括构造函数/析构函数)声明/定义名称之前或在控制语句之前的一组 C++11 属性之后添加换行,即 ifswitch(包括 casedefault 标签),forwhile 语句。

可能的值

  • ABS_Always (在配置中:Always) 始终在属性之后添加换行。

    [[maybe_unused]]
    const int i;
    [[gnu::const]] [[maybe_unused]]
    int j;
    
    [[nodiscard]]
    inline int f();
    [[gnu::const]] [[nodiscard]]
    int g();
    
    [[likely]]
    if (a)
      f();
    else
      g();
    
    switch (b) {
    [[unlikely]]
    case 1:
      ++b;
      break;
    [[likely]]
    default:
      return;
    }
    
  • ABS_Leave (在配置中:Leave) 保留属性之后的换行符。

    [[maybe_unused]] const int i;
    [[gnu::const]] [[maybe_unused]]
    int j;
    
    [[nodiscard]] inline int f();
    [[gnu::const]] [[nodiscard]]
    int g();
    
    [[likely]] if (a)
      f();
    else
      g();
    
    switch (b) {
    [[unlikely]] case 1:
      ++b;
      break;
    [[likely]]
    default:
      return;
    }
    
  • ABS_Never (在配置中:Never) 从不在属性之后添加换行。

    [[maybe_unused]] const int i;
    [[gnu::const]] [[maybe_unused]] int j;
    
    [[nodiscard]] inline int f();
    [[gnu::const]] [[nodiscard]] int g();
    
    [[likely]] if (a)
      f();
    else
      g();
    
    switch (b) {
    [[unlikely]] case 1:
      ++b;
      break;
    [[likely]] default:
      return;
    }
    
BreakAfterJavaFieldAnnotations (Boolean) clang-format 3.8

在 Java 文件中字段上的每个注解之后添加换行。

true:                                  false:
@Partial                       vs.     @Partial @Mock DataLoad loader;
@Mock
DataLoad loader;
BreakAfterReturnType (ReturnTypeBreakingStyle) clang-format 19

要使用的函数声明返回类型断行样式。

可能的值

  • RTBS_None (在配置中:None) 此选项已弃用。请参见下面的 Automatic

  • RTBS_Automatic (在配置中:Automatic) 根据 PenaltyReturnTypeOnItsOwnLine 在返回类型之后添加换行。

    class A {
      int f() { return 0; };
    };
    int f();
    int f() { return 1; }
    int
    LongName::AnotherLongName();
    
  • RTBS_ExceptShortType (在配置中:ExceptShortType) 与上面的 Automatic 相同,除了在短返回类型之后不添加换行。

    class A {
      int f() { return 0; };
    };
    int f();
    int f() { return 1; }
    int LongName::
        AnotherLongName();
    
  • RTBS_All (在配置中:All) 始终在返回类型之后添加换行。

    class A {
      int
      f() {
        return 0;
      };
    };
    int
    f();
    int
    f() {
      return 1;
    }
    int
    LongName::AnotherLongName();
    
  • RTBS_TopLevel (在配置中:TopLevel) 始终在顶层函数的返回类型之后添加换行。

    class A {
      int f() { return 0; };
    };
    int
    f();
    int
    f() {
      return 1;
    }
    int
    LongName::AnotherLongName();
    
  • RTBS_AllDefinitions (在配置中:AllDefinitions) 始终在函数定义的返回类型之后添加换行。

    class A {
      int
      f() {
        return 0;
      };
    };
    int f();
    int
    f() {
      return 1;
    }
    int
    LongName::AnotherLongName();
    
  • RTBS_TopLevelDefinitions (在配置中:TopLevelDefinitions) 始终在顶层定义的返回类型之后添加换行。

    class A {
      int f() { return 0; };
    };
    int f();
    int
    f() {
      return 1;
    }
    int
    LongName::AnotherLongName();
    
BreakArrays (Boolean) clang-format 16

如果为 true,clang-format 将始终在 Json 数组 [ 之后添加换行,否则它将扫描到结束 ] 以确定是否应该在元素之间添加换行(与 prettier 兼容)。

注意

目前此选项仅用于格式化 JSON。

true:                                  false:
[                          vs.      [1, 2, 3, 4]
  1,
  2,
  3,
  4
]
BreakBeforeBinaryOperators (BinaryOperatorStyle) clang-format 3.6

包裹二元运算符的方式。

可能的值

  • BOS_None (在配置中:None) 在运算符之后添加换行。

    LooooooooooongType loooooooooooooooooooooongVariable =
        someLooooooooooooooooongFunction();
    
    bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +
                         aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==
                     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
                 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >
                     ccccccccccccccccccccccccccccccccccccccccc;
    
  • BOS_NonAssignment (在配置中:NonAssignment) 在非赋值运算符之前添加换行。

    LooooooooooongType loooooooooooooooooooooongVariable =
        someLooooooooooooooooongFunction();
    
    bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                         + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                     == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                 && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                        > ccccccccccccccccccccccccccccccccccccccccc;
    
  • BOS_All (在配置中:All) 在运算符之前添加换行。

    LooooooooooongType loooooooooooooooooooooongVariable
        = someLooooooooooooooooongFunction();
    
    bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                         + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                     == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                 && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                        > ccccccccccccccccccccccccccccccccccccccccc;
    
BreakBeforeBraces (BraceBreakingStyle) clang-format 3.7

要使用的大括号断行样式。

可能的值

  • BS_Attach (在配置中:Attach) 始终将大括号附加到周围的环境。

    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
    
  • BS_Linux (在配置中:Linux) 与 Attach 相似,但在函数、命名空间和类定义之前添加换行。

    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
    
  • BS_Mozilla (在配置中:Mozilla) 与 Attach 相似,但在枚举、函数和记录定义之前添加换行。

    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
    
  • BS_Stroustrup (在配置中:Stroustrup) 与 Attach 相似,但在函数定义、catchelse 之前添加换行。

    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
    
  • BS_Allman (在配置中:Allman) 始终在大括号之前添加换行。

    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
    
  • BS_Whitesmiths (在配置中:Whitesmiths) 与 Allman 相似,但始终缩进大括号并将代码与大括号对齐。

    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
    
  • BS_GNU (在配置中:GNU) 始终在大括号之前添加换行,并将控制语句的大括号额外缩进一级,而类、函数或其他定义的大括号则不缩进。

    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
    
  • BS_WebKit (在配置中:WebKit) 与 Attach 相似,但在函数之前添加换行。

    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
    
  • BS_Custom (在配置中:Custom) 配置 BraceWrapping 中的每个括号。

BreakBeforeConceptDeclarations (BreakBeforeConceptDeclarationsStyle) clang-format 12

要使用的概念声明样式。

可能的值

  • BBCDS_Never (在配置中:Never) 将模板声明行与 concept 保持在一起。

    template <typename T> concept C = ...;
    
  • BBCDS_Allowed (在配置中:Allowed) 允许在模板声明和 concept 之间换行。实际行为取决于内容和换行规则和惩罚。

  • BBCDS_Always (在配置中:Always) 始终在 concept 之前换行,将其放在模板声明后的行中。

    template <typename T>
    concept C = ...;
    
BreakBeforeInlineASMColon (BreakBeforeInlineASMColonStyle) clang-format 16

要使用的内联 ASM 冒号样式。

可能的值

  • BBIAS_Never (在配置中:Never) 内联 ASM 冒号之前不换行。

    asm volatile("string", : : val);
    
  • BBIAS_OnlyMultiline (在配置中:OnlyMultiline) 如果行长超过列限制,则在内联 ASM 冒号之前换行。

    asm volatile("string", : : val);
    asm("cmoveq %1, %2, %[result]"
        : [result] "=r"(result)
        : "r"(test), "r"(new), "[result]"(old));
    
  • BBIAS_Always (在配置中:Always) 始终在内联 ASM 冒号之前换行。

    asm volatile("string",
                 :
                 : val);
    
BreakBeforeTernaryOperators (Boolean) clang-format 3.7

如果为 true,则三元运算符将放在换行符之后。

true:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription
    ? firstValue
    : SecondValueVeryVeryVeryVeryLong;

false:
veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongDescription ?
    firstValue :
    SecondValueVeryVeryVeryVeryLong;
BreakBinaryOperations (BreakBinaryOperationsStyle) clang-format 20

要使用的 break 构造函数初始化程序样式。

可能的值

  • BBO_Never (在配置中:Never) 不要中断二元运算。

    aaa + bbbb * ccccc - ddddd +
    eeeeeeeeeeeeeeee;
    
  • BBO_OnePerLine (在配置中:OnePerLine) 二元运算要么全部在同一行上,要么每个运算都有一行。

    aaa +
    bbbb *
    ccccc -
    ddddd +
    eeeeeeeeeeeeeeee;
    
  • BBO_RespectPrecedence (在配置中:RespectPrecedence) 超出列限制的特定优先级的二元运算将每行一个。

    aaa +
    bbbb * ccccc -
    ddddd +
    eeeeeeeeeeeeeeee;
    
BreakConstructorInitializers (BreakConstructorInitializersStyle) clang-format 5

要使用的 break 构造函数初始化程序样式。

可能的值

  • BCIS_BeforeColon (在配置中:BeforeColon) 在冒号之前和逗号之后中断构造函数初始化程序。

    Constructor()
        : initializer1(),
          initializer2()
    
  • BCIS_BeforeComma (在配置中:BeforeComma) 在冒号和逗号之前中断构造函数初始化程序,并将逗号与冒号对齐。

    Constructor()
        : initializer1()
        , initializer2()
    
  • BCIS_AfterColon (在配置中:AfterColon) 在冒号和逗号之后中断构造函数初始化程序。

    Constructor() :
        initializer1(),
        initializer2()
    
BreakFunctionDefinitionParameters (Boolean) clang-format 19

如果为 true,clang-format 将始终在函数定义参数之前换行。

true:
void functionDefinition(
         int A, int B) {}

false:
void functionDefinition(int A, int B) {}
BreakInheritanceList (BreakInheritanceListStyle) clang-format 7

要使用的继承列表样式。

可能的值

  • BILS_BeforeColon (在配置中:BeforeColon) 在冒号之前和逗号之后中断继承列表。

    class Foo
        : Base1,
          Base2
    {};
    
  • BILS_BeforeComma (在配置中:BeforeComma) 在冒号和逗号之前中断继承列表,并将逗号与冒号对齐。

    class Foo
        : Base1
        , Base2
    {};
    
  • BILS_AfterColon (在配置中:AfterColon) 在冒号和逗号之后中断继承列表。

    class Foo :
        Base1,
        Base2
    {};
    
  • BILS_AfterComma (在配置中:AfterComma) 仅在逗号之后中断继承列表。

    class Foo : Base1,
                Base2
    {};
    
BreakStringLiterals (Boolean) clang-format 3.9

允许在格式化时中断字符串文字。

在 C、C++ 和 Objective-C 中

true:
const char* x = "veryVeryVeryVeryVeryVe"
                "ryVeryVeryVeryVeryVery"
                "VeryLongString";

false:
const char* x =
    "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";

在 C# 和 Java 中

true:
string x = "veryVeryVeryVeryVeryVe" +
           "ryVeryVeryVeryVeryVery" +
           "VeryLongString";

false:
string x =
    "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";

C# 插入字符串不会中断。

在 Verilog 中

true:
string x = {"veryVeryVeryVeryVeryVe",
            "ryVeryVeryVeryVeryVery",
            "VeryLongString"};

false:
string x =
    "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
BreakTemplateDeclarations (BreakTemplateDeclarationsStyle) clang-format 19

要使用的模板声明中断样式。

可能的值

  • BTDS_Leave (在配置中:Leave) 不要更改声明之前的换行符。

    template <typename T>
    T foo() {
    }
    template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
                                int bbbbbbbbbbbbbbbbbbbbb) {
    }
    
  • BTDS_No (在配置中:No) 不要强制在声明之前换行。 PenaltyBreakTemplateDeclaration 将被考虑在内。

    template <typename T> T foo() {
    }
    template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
                                int bbbbbbbbbbbbbbbbbbbbb) {
    }
    
  • BTDS_MultiLine (在配置中:MultiLine) 仅当以下声明跨多行时,才强制在模板声明之后换行。

    template <typename T> T foo() {
    }
    template <typename T>
    T foo(int aaaaaaaaaaaaaaaaaaaaa,
          int bbbbbbbbbbbbbbbbbbbbb) {
    }
    
  • BTDS_Yes (在配置中:Yes) 始终在模板声明之后换行。

    template <typename T>
    T foo() {
    }
    template <typename T>
    T foo(int aaaaaaaaaaaaaaaaaaaaa,
          int bbbbbbbbbbbbbbbbbbbbb) {
    }
    
ColumnLimit (Unsigned) clang-format 3.7

列限制。

0 的列限制表示没有列限制。在这种情况下,clang-format 将尊重输入在语句中的换行决定,除非它们与其他规则相矛盾。

CommentPragmas (String) clang-format 3.7

描述具有特殊含义的注释的正则表达式,这些注释不应拆分成行或以其他方式更改。

// CommentPragmas: '^ FOOBAR pragma:'
// Will leave the following line unaffected
#include <vector> // FOOBAR pragma: keep
CompactNamespaces (Boolean) clang-format 5

如果为 true,则连续的命名空间声明将在同一行上。如果为 false,则每个命名空间都在新行上声明。

true:
namespace Foo { namespace Bar {
}}

false:
namespace Foo {
namespace Bar {
}
}

如果它不适合单行,则溢出的命名空间将被包装

namespace Foo { namespace Bar {
namespace Extra {
}}}
ConstructorInitializerAllOnOneLineOrOnePerLine (Boolean) clang-format 3.7

此选项已弃用。请参阅 PackConstructorInitializersCurrentLine

ConstructorInitializerIndentWidth (Unsigned) clang-format 3.7

用于缩进构造函数初始化程序列表以及继承列表的字符数。

ContinuationIndentWidth (Unsigned) clang-format 3.7

行继续的缩进宽度。

ContinuationIndentWidth: 2

int i =         //  VeryVeryVeryVeryVeryLongComment
  longFunction( // Again a long comment
    arg);
Cpp11BracedListStyle (Boolean) clang-format 3.4

如果为 true,则将大括号列表格式化为最适合 C++11 大括号列表。

重要区别:- 大括号列表内部没有空格。- 在右大括号之前没有换行符。- 使用继续缩进进行缩进,而不是使用块缩进。

从根本上说,C++11 大括号列表的格式与函数调用在它们位置的格式完全相同。如果大括号列表紧跟一个名称(例如类型或变量名称),clang-format 将格式化得好像 {} 是具有该名称的函数调用的括号。如果没有名称,则假定为空名称。

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 };
DeriveLineEnding (Boolean) clang-format 10

此选项已弃用。请参阅 LineEndingDeriveLFDeriveCRLF

DerivePointerAlignment (Boolean) clang-format 3.7

如果为 true,则分析格式化的文件以查找 &* 的最常见对齐方式。指针和引用对齐方式将根据在文件中找到的首选项进行更新。然后 PointerAlignment 仅用作后备。

DisableFormat (Boolean) clang-format 3.7

完全禁用格式化。

EmptyLineAfterAccessModifier (EmptyLineAfterAccessModifierStyle) clang-format 13

定义何时在访问修饰符之后放置空行。 EmptyLineBeforeAccessModifier 配置处理两个访问修饰符之间的空行数。

可能的值

  • ELAAMS_Never (在配置中:Never) 删除访问修饰符后的所有空行。

    struct foo {
    private:
      int i;
    protected:
      int j;
      /* comment */
    public:
      foo() {}
    private:
    protected:
    };
    
  • ELAAMS_Leave (在配置中:Leave) 保留访问修饰符后的现有空行。MaxEmptyLinesToKeep 将被应用。

  • ELAAMS_Always (在配置中:Always) 如果没有空行,则始终在访问修饰符之后添加空行。MaxEmptyLinesToKeep 也会被应用。

    struct foo {
    private:
    
      int i;
    protected:
    
      int j;
      /* comment */
    public:
    
      foo() {}
    private:
    
    protected:
    
    };
    
EmptyLineBeforeAccessModifier (EmptyLineBeforeAccessModifierStyle) clang-format 12

定义在哪些情况下在访问修饰符之前放置空行。

可能的值

  • ELBAMS_Never (在配置中:Never) 删除访问修饰符之前的所有空行。

    struct foo {
    private:
      int i;
    protected:
      int j;
      /* comment */
    public:
      foo() {}
    private:
    protected:
    };
    
  • ELBAMS_Leave (在配置中:Leave) 保留访问修饰符之前的现有空行。

  • ELBAMS_LogicalBlock (在配置中:LogicalBlock) 仅当访问修饰符开始一个新的逻辑块时添加空行。逻辑块是包含一个或多个成员字段或函数的组。

    struct foo {
    private:
      int i;
    
    protected:
      int j;
      /* comment */
    public:
      foo() {}
    
    private:
    protected:
    };
    
  • ELBAMS_Always (在配置中:Always) 始终在访问修饰符之前添加空行,除非访问修饰符位于结构体或类定义的开头。

    struct foo {
    private:
      int i;
    
    protected:
      int j;
      /* comment */
    
    public:
      foo() {}
    
    private:
    
    protected:
    };
    
ExperimentalAutoDetectBinPacking (Boolean) clang-format 3.7

如果 true,clang-format 会检测函数调用和定义是否采用每行一个参数的格式进行格式化。

每个调用可以是 bin-packed、每行一个或不确定。如果它是不确定的,例如完全在一行上,但需要做出决定,clang-format 会分析输入文件是否还有其他 bin-packed 案例,并相应地采取行动。

注意

这是一个实验性标志,可能会消失或被重命名。请勿在配置文件等中使用它。使用风险自负。

FixNamespaceComments (Boolean) clang-format 5

如果 true,clang-format 会为命名空间添加缺少的命名空间结束注释,并修复无效的现有注释。这不会影响由 ShortNamespaceLines 控制的短命名空间。

true:                                  false:
namespace longNamespace {      vs.     namespace longNamespace {
void foo();                            void foo();
void bar();                            void bar();
} // namespace a                       }
namespace shortNamespace {             namespace shortNamespace {
void baz();                            void baz();
}                                      }
ForEachMacros (List of Strings) clang-format 3.7

一个宏向量,应该被解释为 foreach 循环而不是函数调用。

这些宏应该具有以下形式:

FOREACH(<variable-declaration>, ...)
  <loop-body>

在 .clang-format 配置文件中,可以像这样配置它

ForEachMacros: [RANGES_FOR, FOREACH]

例如:BOOST_FOREACH。

IfMacros (List of Strings) clang-format 13

一个宏向量,应该被解释为条件语句而不是函数调用。

这些宏应该具有以下形式:

IF(...)
  <conditional-body>
else IF(...)
  <conditional-body>

在 .clang-format 配置文件中,可以像这样配置它

IfMacros: [IF]

例如:KJ_IF_MAYBE

IncludeBlocks (IncludeBlocksStyle) clang-format 6

根据值的不同,可以将多个 #include 块按一个排序,并根据类别进行划分。

可能的值

  • IBS_Preserve (在配置中:Preserve) 分别对每个 #include 块进行排序。

    #include "b.h"               into      #include "b.h"
    
    #include <lib/main.h>                  #include "a.h"
    #include "a.h"                         #include <lib/main.h>
    
  • IBS_Merge (在配置中:Merge) 将多个 #include 块合并在一起,并按一个排序。

    #include "b.h"               into      #include "a.h"
                                           #include "b.h"
    #include <lib/main.h>                  #include <lib/main.h>
    #include "a.h"
    
  • IBS_Regroup (在配置中:Regroup) 将多个 #include 块合并在一起,并按一个排序。然后根据类别优先级将其拆分为组。请参见 IncludeCategories

    #include "b.h"               into      #include "a.h"
                                           #include "b.h"
    #include <lib/main.h>
    #include "a.h"                         #include <lib/main.h>
    
IncludeCategories (List of IncludeCategories) clang-format 3.8

用于对 #includes 进行排序的不同 #include 类别的正则表达式。

支持 POSIX 扩展 正则表达式。

这些正则表达式与包含文件的名称(包括 <> 或 “”)匹配,按顺序进行匹配。将分配第一个匹配的正则表达式的值,#includes 将首先根据类别编号的升序进行排序,然后在每个类别中按字母顺序进行排序。

如果所有正则表达式都不匹配,则分配 INT_MAX 作为类别。源文件的 main 标头会自动获得类别 0,因此它通常会保留在 #includes 的开头(https://llvm.net.cn/docs/CodingStandards.html#include-style)。但是,如果您有一些始终需要放在首位的标头,也可以分配负优先级。

还有一个可选的第三个字段 SortPriority,可以在 IncludeBlocks = IBS_Regroup 时使用,用于定义 #includes 的排序优先级。Priority 的值定义了 #include blocks 的顺序,并允许对不同优先级的 #includes 进行分组。如果未分配 SortPriority,则默认情况下将设置为 Priority 的值。

每个正则表达式都可以通过字段 CaseSensitive 来标记为区分大小写,默认情况下不区分大小写。

要在 .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
IncludeIsMainRegex (String) clang-format 3.9

指定文件到 main 包含映射中允许的后缀的正则表达式。

在猜测 #include 是否是“main”包含文件(以分配类别 0,参见上文)时,请使用此允许后缀的正则表达式来匹配标头词干。将进行部分匹配,因此: - “” 意味着“任意后缀” - “$” 意味着“无后缀”

例如,如果配置为“(_test)?$”,那么标头 a.h 将在 a.cc 和 a_test.cc 中都被视为“main”包含文件。

IncludeIsMainSourceRegex (String) clang-format 10

指定要格式化的文件的正则表达式,这些文件允许被视为文件到 main 包含映射中的“main”。

默认情况下,clang-format 仅在文件以以下扩展名结尾时才将其视为“main”:.c.cc.cpp.c++.cxx.m.mm。对于这些文件,会进行“main”包含文件的猜测(以分配类别 0,参见上文)。此配置选项允许将其他后缀和扩展名用于要视为“main”的文件。

例如,如果此选项配置为 (Impl\.hpp)$,则文件 ClassImpl.hpp 被视为“main”(除了 Class.cClass.ccClass.cpp 等),“main 包含文件”逻辑将被执行(在后面的阶段,IncludeIsMainRegex 设置也会被尊重)。如果没有设置此选项,ClassImpl.hpp 不会将 main 包含文件放在其他包含文件之前。

IndentAccessModifiers (Boolean) clang-format 13

指定访问修饰符是否应该具有自己的缩进级别。

false 时,访问修饰符相对于记录成员进行缩进(或反缩进),并尊重 AccessModifierOffset。记录成员的缩进级别比记录低一级。当 true 时,访问修饰符将获得自己的缩进级别。因此,无论访问修饰符是否存在,记录成员的缩进级别始终比记录低两级。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;
}                                      }
IndentCaseBlocks (Boolean) clang-format 11

将 case 标签块的缩进级别从 case 标签缩进一级。

false 时,case 标签后的块使用与 case 标签相同的缩进级别,将 case 标签视为与 if 语句相同。当 true 时,该块将像作用域块一样进行缩进。

false:                                 true:
switch (fool) {                vs.     switch (fool) {
case 1: {                              case 1:
  bar();                                 {
} break;                                   bar();
default: {                               }
  plop();                                break;
}                                      default:
}                                        {
                                           plop();
                                         }
                                       }
IndentCaseLabels (Boolean) clang-format 3.3

将 case 标签的缩进级别从 switch 语句缩进一级。

false 时,使用与 switch 语句相同的缩进级别。switch 语句主体始终比 case 标签缩进一级(除了 case 标签后的第一个块,它本身会缩进代码,除非启用了 IndentCaseBlocks)。

false:                                 true:
switch (fool) {                vs.     switch (fool) {
case 1:                                  case 1:
  bar();                                   bar();
  break;                                   break;
default:                                 default:
  plop();                                  plop();
}                                      }
IndentExternBlock (IndentExternBlockStyle) clang-format 11

IndentExternBlockStyle 是 extern 块缩进的类型。

可能的值

  • IEBS_AfterExternBlock (在配置中:AfterExternBlock) 向后兼容 AfterExternBlock 的缩进。

    IndentExternBlock: AfterExternBlock
    BraceWrapping.AfterExternBlock: true
    extern "C"
    {
        void foo();
    }
    
    IndentExternBlock: AfterExternBlock
    BraceWrapping.AfterExternBlock: false
    extern "C" {
    void foo();
    }
    
  • IEBS_NoIndent (在配置中:NoIndent) 不缩进 extern 块。

    extern "C" {
    void foo();
    }
    
  • IEBS_Indent (在配置中:Indent) 缩进 extern 块。

    extern "C" {
      void foo();
    }
    
IndentGotoLabels (Boolean) clang-format 10

缩进 goto 标签。

false 时,goto 标签将左对齐。

true:                                  false:
int f() {                      vs.     int f() {
  if (foo()) {                           if (foo()) {
  label1:                              label1:
    bar();                                 bar();
  }                                      }
label2:                                label2:
  return 1;                              return 1;
}                                      }
IndentPPDirectives (PPDirectiveIndentStyle) clang-format 6

要使用的预处理器指令缩进样式。

可能的值

  • PPDIS_None (在配置中: None) 不缩进任何指令。

    #if FOO
    #if BAR
    #include <foo>
    #endif
    #endif
    
  • PPDIS_AfterHash (在配置中: AfterHash) 在井号之后缩进指令。

    #if FOO
    #  if BAR
    #    include <foo>
    #  endif
    #endif
    
  • PPDIS_BeforeHash (在配置中: BeforeHash) 在井号之前缩进指令。

    #if FOO
      #if BAR
        #include <foo>
      #endif
    #endif
    
IndentRequiresClause (Boolean) clang-format 15

缩进模板中的 requires 子句。这仅在 RequiresClausePositionOwnLineOwnLineWithBraceWithFollowing 时适用。

在 clang-format 12、13 和 14 中,它被称为 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) {
  //....
}
IndentWidth (Unsigned) clang-format 3.7

用于缩进的列数。

IndentWidth: 3

void f() {
   someFunction();
   if (true, false) {
      f();
   }
}
IndentWrappedFunctionNames (Boolean) clang-format 3.7

如果函数定义或声明在类型之后换行,则缩进。

true:
LoooooooooooooooooooooooooooooooooooooooongReturnType
    LoooooooooooooooooooooooooooooooongFunctionDeclaration();

false:
LoooooooooooooooooooooooooooooooooooooooongReturnType
LoooooooooooooooooooooooooooooooongFunctionDeclaration();
InsertBraces (Boolean) clang-format 15

在 C++ 中的控制语句 (ifelsefordowhile) 之后插入大括号,除非控制语句在宏定义内,或者大括号将包含预处理器指令。

警告

将此选项设置为 true 可能会导致代码格式不正确,因为 clang-format 缺乏完整的语义信息。因此,应格外注意审查此选项所做的代码更改。

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);
InsertNewlineAtEOF (Boolean) clang-format 16

如果文件末尾缺少换行符,则插入一个换行符。

InsertTrailingCommas (TrailingCommaStyle) clang-format 11

如果设置为 TCS_Wrapped,将在跨越多行的容器字面量(数组和对象)中插入尾部逗号。它目前仅适用于 JavaScript,默认情况下已禁用 TCS_NoneInsertTrailingCommas 不能与 BinPackArguments 一起使用,因为插入逗号会禁用 bin-packing。

TSC_Wrapped:
const someArray = [
aaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaa,
//                        ^ inserted
]

可能的值

  • TCS_None (在配置中: None) 不插入尾部逗号。

  • TCS_Wrapped (在配置中: Wrapped) 在跨越多行的容器字面量中插入尾部逗号。请注意,从概念上讲,这与 bin-packing 不兼容,因为尾部逗号用作容器应以每行一个的格式格式化的指示符(即,不进行 bin-packing)。因此,插入尾部逗号会抵消 bin-packing。

IntegerLiteralSeparator (IntegerLiteralSeparatorStyle) clang-format 16

格式化整数字面量分隔符 (' 用于 C++ 和 _ 用于 C#、Java 和 JavaScript)。

嵌套配置标志

不同基数的整数字面量的分隔符格式。

如果为负数,则删除分隔符。如果为 0,则保留字面量原样。如果为正数,则从最右边的数字开始在数字之间插入分隔符。

例如,下面的配置将在二进制字面量中保留分隔符,在十进制字面量中插入分隔符以将数字分成 3 组,并在十六进制字面量中删除分隔符。

IntegerLiteralSeparator:
  Binary: 0
  Decimal: 3
  Hex: -1

您还可以指定整数字面量必须具有的最小数字数 (BinaryMinDigitsDecimalMinDigitsHexMinDigits),以便插入分隔符。

  • int8_t Binary 在二进制字面量中格式化分隔符。

    /* -1: */ b = 0b100111101101;
    /*  0: */ b = 0b10011'11'0110'1;
    /*  3: */ b = 0b100'111'101'101;
    /*  4: */ b = 0b1001'1110'1101;
    
  • int8_t BinaryMinDigits 在二进制字面量中格式化分隔符,具有最小数字数。

    // Binary: 3
    // BinaryMinDigits: 7
    b1 = 0b101101;
    b2 = 0b1'101'101;
    
  • int8_t Decimal 在十进制字面量中格式化分隔符。

    /* -1: */ d = 18446744073709550592ull;
    /*  0: */ d = 184467'440737'0'95505'92ull;
    /*  3: */ d = 18'446'744'073'709'550'592ull;
    
  • int8_t DecimalMinDigits 在十进制字面量中格式化分隔符,具有最小数字数。

    // Decimal: 3
    // DecimalMinDigits: 5
    d1 = 2023;
    d2 = 10'000;
    
  • int8_t Hex 在十六进制字面量中格式化分隔符。

    /* -1: */ h = 0xDEADBEEFDEADBEEFuz;
    /*  0: */ h = 0xDEAD'BEEF'DE'AD'BEE'Fuz;
    /*  2: */ h = 0xDE'AD'BE'EF'DE'AD'BE'EFuz;
    
  • int8_t HexMinDigits 在十六进制字面量中格式化分隔符,具有最小数字数。

    // Hex: 2
    // HexMinDigits: 6
    h1 = 0xABCDE;
    h2 = 0xAB'CD'EF;
    
JavaImportGroups (List of Strings) clang-format 8

一个按 Java 导入所需的组排序的前缀向量。

一组的前缀可以是另一组的子集 - 始终匹配最长的前缀。在一个组内,导入按字典顺序排序。静态导入单独分组,并遵循相同的组规则。默认情况下,静态导入位于非静态导入之前,但此行为会因另一个选项 SortJavaStaticImport 而改变。

在 .clang-format 配置文件中,可以像下面的 yaml 示例一样进行配置。这将导致导入像下面的 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;
JavaScriptQuotes (JavaScriptQuoteStyle) clang-format 3.9

用于 JavaScript 字符串的 JavaScriptQuoteStyle。

可能的值

  • JSQS_Leave (在配置中: Leave) 保留字符串引号原样。

    string1 = "foo";
    string2 = 'bar';
    
  • JSQS_Single (在配置中: Single) 始终使用单引号。

    string1 = 'foo';
    string2 = 'bar';
    
  • JSQS_Double (在配置中: Double) 始终使用双引号。

    string1 = "foo";
    string2 = "bar";
    
JavaScriptWrapImports (Boolean) clang-format 3.9

是否包装 JavaScript import/export 语句。

true:
import {
    VeryLongImportsAreAnnoying,
    VeryLongImportsAreAnnoying,
    VeryLongImportsAreAnnoying,
} from "some/module.js"

false:
import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
KeepEmptyLines (KeepEmptyLinesStyle) clang-format 19

保留哪些空行。有关保留多少个连续空行的信息,请参见 MaxEmptyLinesToKeep

嵌套配置标志

关于保留哪些空行的选项。

例如,下面的配置将删除文件开头、文件末尾和块开头的空行。

KeepEmptyLines:
  AtEndOfFile: false
  AtStartOfBlock: false
  AtStartOfFile: false
  • bool AtEndOfFile 保留文件末尾的空行。

  • bool AtStartOfBlock 保留块开头的空行。

    true:                                  false:
    if (foo) {                     vs.     if (foo) {
                                             bar();
      bar();                               }
    }
    
  • bool AtStartOfFile 保留文件开头的空行。

KeepEmptyLinesAtEOF (Boolean) clang-format 17

此选项已弃用。请参见 KeepEmptyLinesAtEndOfFile

KeepEmptyLinesAtTheStartOfBlocks (Boolean) clang-format 3.7

此选项已弃用。请参见 KeepEmptyLinesAtStartOfBlock

KeepFormFeed (Boolean) clang-format 20

如果换行符紧接在换行符之前和之后,则保留换页符。在空格范围内的多个换页符和换行符将替换为单个换行符和换页符,后面跟着剩余的换行符。

LambdaBodyIndentation (LambdaBodyIndentationKind) clang-format 13

Lambda 主体的缩进样式。 Signature (默认) 使 Lambda 主体相对于签名的缩进级别缩进一个额外级别。 OuterScope 强制 Lambda 主体相对于包含 Lambda 签名的父作用域缩进一个额外级别。

可能的值

  • LBI_Signature (在配置中: Signature) 相对于 Lambda 签名对齐 Lambda 主体。这是默认设置。

    someMethod(
        [](SomeReallyLongLambdaSignatureArgument foo) {
          return;
        });
    
  • LBI_OuterScope (在配置中: OuterScope) 对于块作用域内的语句,相对于 Lambda 签名所在的外部作用域的缩进级别对齐 Lambda 主体。

    someMethod(
        [](SomeReallyLongLambdaSignatureArgument foo) {
      return;
    });
    
    someMethod(someOtherMethod(
        [](SomeReallyLongLambdaSignatureArgument foo) {
      return;
    }));
    
Language (LanguageKind) clang-format 3.5

语言,此格式样式针对它。

可能的值

行尾 (LineEndingStyle) clang-format 16

要使用的行尾样式 (\n\r\n)。

可能的值

  • LE_LF (在配置中:LF) 使用 \n

  • LE_CRLF (在配置中:CRLF) 使用 \r\n

  • LE_DeriveLF (在配置中:DeriveLF) 使用 \n,除非输入中以 \r\n 结尾的行更多。

  • LE_DeriveCRLF (在配置中:DeriveCRLF) 使用 \r\n,除非输入中以 \n 结尾的行更多。

宏块开始 (String) clang-format 3.7

与开始一个块的宏匹配的正则表达式。

# 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
宏块结束 (String) clang-format 3.7

与结束一个块的宏匹配的正则表达式。

(List of Strings) clang-format 17

一个以 <definition>=<expansion> 格式表示的宏列表。

代码将在宏展开后进行解析,以确定如何解释和格式化宏参数。

例如,代码

A(a*b);

通常会被解释为对函数 A 的调用,乘法表达式会被格式化为 a * b

如果我们指定宏定义

Macros:
- A(x)=x

代码现在将被解析为类型为 a* 的变量 b 的声明,并被格式化为 a* b(取决于指针绑定规则)。

功能和限制
  • 函数式宏和对象式宏都受支持。

  • 宏参数必须在展开中使用且仅使用一次。

  • 不支持递归展开;引用其他宏的宏将被忽略。

  • 支持按元数重载:例如,给定宏定义 A=x, A()=y, A(a)=a

A; -> x;
A(); -> y;
A(z); -> z;
A(a, b); // will not be expanded.
主要包含字符 (MainIncludeCharDiscriminator) clang-format 19

在猜测 #include 是否为“主要”包含文件时,只考虑使用指定字符的包含指令。

可能的值

  • MICD_Quote (在配置中:Quote) 主要包含文件使用引号:#include "foo.hpp" (默认值)。

  • MICD_AngleBracket (在配置中:AngleBracket) 主要包含文件使用尖括号:#include <foo.hpp>

  • MICD_Any (在配置中:Any) 主要包含文件使用引号或尖括号。

最大保留空行数 (Unsigned) clang-format 3.7

要保留的连续空行的最大数量。

MaxEmptyLinesToKeep: 1         vs.     MaxEmptyLinesToKeep: 0
int f() {                              int f() {
  int = 1;                                 int i = 1;
                                           i = foo();
  i = foo();                               return i;
                                       }
  return i;
}
命名空间缩进 (NamespaceIndentationKind) clang-format 3.7

用于命名空间的缩进。

可能的值

  • NI_None (在配置中:None) 不要在命名空间中缩进。

    namespace out {
    int i;
    namespace in {
    int i;
    }
    }
    
  • NI_Inner (在配置中:Inner) 仅在内部命名空间中缩进(嵌套在其他命名空间中)。

    namespace out {
    int i;
    namespace in {
      int i;
    }
    }
    
  • NI_All (在配置中:All) 在所有命名空间中缩进。

    namespace out {
      int i;
      namespace in {
        int i;
      }
    }
    
命名空间宏 (List of Strings) clang-format 9

用于打开命名空间块的宏向量。

这些宏应该具有以下形式:

NAMESPACE(<namespace-name>, ...) {
  <namespace-content>
}

例如:TESTSUITE

ObjCBinPackProtocolList (BinPackStyle) clang-format 7

控制将 Objective-C 协议一致性列表项尽可能多地打包成几行,前提是它们超过了 ColumnLimit

如果为 Auto (默认值),则委托给 BinPackParameters 中的值。如果该值为 BinPack,则在 Objective-C 协议一致性列表项超过 ColumnLimit 时,尽可能多地将其打包成几行。

如果为 Always,则在 Objective-C 协议一致性列表项超过 ColumnLimit 时,始终将其尽可能多地打包成几行。

如果为 Never,则在 Objective-C 协议一致性列表项超过 ColumnLimit 时,将其布局到单独的行上。

Always (or Auto, if BinPackParameters==BinPack):
@interface ccccccccccccc () <
    ccccccccccccc, ccccccccccccc,
    ccccccccccccc, ccccccccccccc> {
}

Never (or Auto, if BinPackParameters!=BinPack):
@interface ddddddddddddd () <
    ddddddddddddd,
    ddddddddddddd,
    ddddddddddddd,
    ddddddddddddd> {
}

可能的值

  • BPS_Auto (在配置中:Auto) 自动确定参数二进制打包行为。

  • BPS_Always (在配置中:Always) 始终二进制打包参数。

  • BPS_Never (在配置中:Never) 从不二进制打包参数。

ObjCBlockIndentWidth (Unsigned) clang-format 3.7

用于缩进 ObjC 块的字符数。

ObjCBlockIndentWidth: 4

[operation setCompletionBlock:^{
    [self onOperationDone];
}];
ObjCBreakBeforeNestedBlockParam (Boolean) clang-format 11

在函数调用中存在嵌套块参数时,将参数列表分解成几行。

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;
         }]
 }
ObjCPropertyAttributeOrder (List of Strings) clang-format 18

ObjC 属性属性应出现的顺序。

代码中的属性将按指定的顺序排序。遇到的任何未在此数组中提及的属性将按稳定顺序最后排序。属性之间的注释将保持属性不变。

警告

使用此选项可能会导致代码格式错误,因为 clang-format 缺乏完整的语义信息。因此,应格外小心地审查此选项所做的代码更改。

ObjCPropertyAttributeOrder: [
    class, direct,
    atomic, nonatomic,
    assign, retain, strong, copy, weak, unsafe_unretained,
    readonly, readwrite, getter, setter,
    nullable, nonnull, null_resettable, null_unspecified
]
ObjCSpaceAfterProperty (Boolean) clang-format 3.7

在 Objective-C 中的 @property 后面添加一个空格,即使用 @property (readonly) 而不是 @property(readonly)

ObjCSpaceBeforeProtocolList (Boolean) clang-format 3.7

在 Objective-C 协议列表之前添加一个空格,即使用 Foo <Protocol> 而不是 Foo<Protocol>

PPIndentWidth (Integer) clang-format 13

用于缩进预处理器语句的列数。当设置为 -1 (默认值) 时,IndentWidth 也用于预处理器语句。

PPIndentWidth: 1

#ifdef __linux__
# define FOO
#else
# define BAR
#endif
PackConstructorInitializers (PackConstructorInitializersStyle) clang-format 14

要使用的打包构造函数初始化器样式。

可能的值

  • PCIS_Never (在配置中:Never) 始终将每个构造函数初始化器放在单独的行上。

    Constructor()
        : a(),
          b()
    
  • PCIS_BinPack (在配置中:BinPack) 二进制打包构造函数初始化器。

    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(),
          cccccccccccccccccccc()
    
  • PCIS_CurrentLine (在配置中:CurrentLine) 如果构造函数初始化器适合当前行,则将其全部放在当前行上。否则,将每个初始化器放在单独的行上。

    Constructor() : a(), b()
    
    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(),
          bbbbbbbbbbbbbbbbbbbb(),
          ddddddddddddd()
    
  • PCIS_NextLine (在配置中:NextLine) 与 PCIS_CurrentLine 相同,只是如果所有构造函数初始化器都无法放入当前行,则尝试将它们放入下一行。

    Constructor() : a(), b()
    
    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
    
    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(),
          bbbbbbbbbbbbbbbbbbbb(),
          cccccccccccccccccccc()
    
  • PCIS_NextLineOnly (在配置中:NextLineOnly) 如果所有构造函数初始化器都适合,则将它们放在下一行。否则,将每个初始化器放在单独的一行。

    Constructor()
        : a(), b()
    
    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
    
    Constructor()
        : aaaaaaaaaaaaaaaaaaaa(),
          bbbbbbbbbbbbbbbbbbbb(),
          cccccccccccccccccccc()
    
PenaltyBreakAssignment (Unsigned) clang-format 5

在赋值运算符周围断开的惩罚。

PenaltyBreakBeforeFirstCallParameter (Unsigned) clang-format 3.7

call( 之后断开函数调用时的惩罚。

PenaltyBreakComment (Unsigned) clang-format 3.7

在注释中引入的每个换行符的惩罚。

PenaltyBreakFirstLessLess (Unsigned) clang-format 3.7

在第一个 << 之前断开的惩罚。

PenaltyBreakOpenParenthesis (Unsigned) clang-format 14

( 之后断开的惩罚。

PenaltyBreakScopeResolution (Unsigned) clang-format 18

:: 之后断开的惩罚。

PenaltyBreakString (Unsigned) clang-format 3.7

在字符串字面量中引入的每个换行符的惩罚。

PenaltyBreakTemplateDeclaration (Unsigned) clang-format 7

在模板声明之后断开的惩罚。

PenaltyExcessCharacter (Unsigned) clang-format 3.7

超出列限制的每个字符的惩罚。

PenaltyIndentedWhitespace (Unsigned) clang-format 12

每个空格缩进字符的惩罚(相对于前导非空格列计数)。

PenaltyReturnTypeOnItsOwnLine (Unsigned) clang-format 3.7

将函数的返回类型放在单独一行的惩罚。

PointerAlignment (PointerAlignmentStyle) clang-format 3.7

指针和引用对齐方式。

可能的值

  • PAS_Left (在配置中:Left) 将指针对齐到左侧。

    int* a;
    
  • PAS_Right (在配置中:Right) 将指针对齐到右侧。

    int *a;
    
  • PAS_Middle (在配置中:Middle) 将指针对齐到中间。

    int * a;
    
QualifierAlignment (QualifierAlignmentStyle) clang-format 14

排列说明符和限定符(例如 const/volatile)的不同方法。

警告

QualifierAlignment 设置为除 Leave 之外的任何值,可能会导致代码格式错误,因为 clang-format 缺乏完整的语义信息。因此,在使用此选项时应格外小心以审查代码更改。

可能的值

  • QAS_Leave (在配置中:Leave) 不要将说明符/限定符更改为左对齐或右对齐(默认值)。

    int const a;
    const int *a;
    
  • QAS_Left (在配置中:Left) 将说明符/限定符更改为左对齐。

    const int a;
    const int *a;
    
  • QAS_Right (在配置中:Right) 将说明符/限定符更改为右对齐。

    int const a;
    int const *a;
    
  • QAS_Custom (在配置中:Custom) 将说明符/限定符更改为基于 QualifierOrder 对齐。使用

    QualifierOrder: [inline, static, type, const]
    
    int const a;
    int const *a;
    
QualifierOrder (List of Strings) clang-format 14

限定符出现的顺序。顺序是一个数组,可以包含以下任何内容

  • const

  • inline

  • static

  • friend

  • constexpr

  • volatile

  • restrict

  • type

注意

它 **必须** 包含 type

位于 type 左侧的项目将放置在类型左侧,并按提供的顺序对齐。位于 type 右侧的项目将放置在类型右侧,并按提供的顺序对齐。

QualifierOrder: [inline, static, type, const, volatile]
RawStringFormats (List of RawStringFormats) clang-format 6

定义用于检测原始字符串中支持的语言代码块的提示。

具有匹配分隔符或匹配封闭函数名的原始字符串将根据在 .clang-format 文件中定义的该语言样式重新格式化,假设该语言已指定。如果 .clang-format 文件中未为特定语言定义任何样式,则使用 BasedOnStyle 给出的预定义样式。如果找不到 BasedOnStyle,则格式基于 LLVM 样式。匹配的分隔符优先于匹配的封闭函数名,用于确定原始字符串内容的语言。

如果指定了规范的分隔符,则如果可能,相同语言的其他分隔符的出现将更新为规范分隔符。

每个语言最多应有一个规范,每个分隔符和封闭函数不应出现在多个规范中。

要在 .clang-format 文件中配置它,请使用

RawStringFormats:
  - Language: TextProto
      Delimiters:
        - pb
        - proto
      EnclosingFunctions:
        - PARSE_TEXT_PROTO
      BasedOnStyle: google
  - Language: Cpp
      Delimiters:
        - cc
        - cpp
      BasedOnStyle: LLVM
      CanonicalDelimiter: cc
ReferenceAlignment (ReferenceAlignmentStyle) clang-format 13

引用对齐方式(覆盖引用的 PointerAlignment)。

可能的值

  • RAS_Pointer (在配置中:Pointer) 像 PointerAlignment 一样对齐引用。

  • RAS_Left (在配置中:Left) 将引用对齐到左侧。

    int& a;
    
  • RAS_Right (在配置中:Right) 将引用对齐到右侧。

    int &a;
    
  • RAS_Middle (在配置中:Middle) 将引用对齐到中间。

    int & a;
    
ReflowComments (ReflowCommentsStyle) clang-format 3.8

注释重新格式化样式。

可能的值

  • RCS_Never (在配置中:Never) 保持注释不变。

    // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
    /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
    /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
         * and a misaligned second line */
    
  • RCS_IndentOnly (在配置中:IndentOnly) 只应用缩进规则,将注释向左或向右移动,而不更改注释内部的格式。

    // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
    /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information */
    /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
     * and a misaligned second line */
    
  • RCS_Always (在配置中:Always) 应用缩进规则并将长注释重新格式化为新行,尝试遵守 ColumnLimit

    // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
    // information
    /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
     * information */
    /* third veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
     * information and a misaligned second line */
    
RemoveBracesLLVM (Boolean) clang-format 14

根据 LLVM 编码风格,移除 C++ 中控制语句(ifelseforwhile)的可选大括号。

警告

此选项将被重命名并扩展以支持其他样式。

警告

将此选项设置为 true 可能会导致代码格式不正确,因为 clang-format 缺乏完整的语义信息。因此,应格外注意审查此选项所做的代码更改。

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();
  }
}
RemoveEmptyLinesInUnwrappedLines (Boolean) clang-format 20

移除未包装行中的空行。

false:                            true:

int c                  vs.        int c = a + b;

    = a + b;

enum : unsigned        vs.        enum : unsigned {
                                    AA = 0,
{                                   BB
  AA = 0,                         } myEnum;
  BB
} myEnum;

while (                vs.        while (true) {
                                  }
    true) {
}
RemoveParentheses (RemoveParenthesesStyle) clang-format 17

移除多余的圆括号。

警告

将此选项设置为除 Leave 之外的任何值可能会导致代码格式错误,因为 clang-format 缺乏完整的语义信息。因此,应格外小心以审查由此选项做出的代码更改。

可能的值

  • RPS_Leave (在配置中:Leave) 不要移除圆括号。

    class __declspec((dllimport)) X {};
    co_return (((0)));
    return ((a + b) - ((c + d)));
    
  • RPS_MultipleParentheses (在配置中:MultipleParentheses) 将多个圆括号替换为单个圆括号。

    class __declspec(dllimport) X {};
    co_return (0);
    return ((a + b) - (c + d));
    
  • RPS_ReturnStatement (在配置中:ReturnStatement) 还会移除 return/co_return 语句中包围表达式的圆括号。

    class __declspec(dllimport) X {};
    co_return 0;
    return (a + b) - (c + d);
    
RemoveSemicolon (Boolean) clang-format 16

移除函数和构造函数/析构函数的结束大括号后的分号。

警告

将此选项设置为 true 可能会导致代码格式不正确,因为 clang-format 缺乏完整的语义信息。因此,应格外注意审查此选项所做的代码更改。

false:                                     true:

int max(int a, int b) {                    int max(int a, int b) {
  return a > b ? a : b;                      return a > b ? a : b;
};                                         }
RequiresClausePosition (RequiresClausePositionStyle) clang-format 15

requires 子句的位置。

可能的值

  • RCPS_OwnLine (在配置中:OwnLine) 始终将 requires 子句放在它自己的行上(可能后面跟着分号)。

    template <typename T>
      requires C<T>
    struct Foo {...
    
    template <typename T>
    void bar(T t)
      requires C<T>;
    
    template <typename T>
      requires C<T>
    void bar(T t) {...
    
    template <typename T>
    void baz(T t)
      requires C<T>
    {...
    
  • RCPS_OwnLineWithBrace (在配置中:OwnLineWithBrace) 与 OwnLine 相同,只是,除非另有禁止,否则将紧随其后的左大括号(函数定义)放在同一行。

    void bar(T t)
      requires C<T> {
      return;
    }
    
    void bar(T t)
      requires C<T> {}
    
    template <typename T>
      requires C<T>
    void baz(T t) {
      ...
    
  • RCPS_WithPreceding (在配置中:WithPreceding) 尝试将子句与声明的前面部分放在一起。对于类模板:坚持模板声明。对于函数模板:坚持模板声明。对于函数声明后跟着 requires 子句:坚持参数列表。

    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>
    {...
    
  • RCPS_WithFollowing (在配置中:WithFollowing) 尝试将 requires 子句与类或函数声明放在一起。

    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> {...
    
  • RCPS_SingleLine (在配置中:SingleLine) 尽可能尝试将所有内容放在同一行。否则,正常的换行规则将接管。

    // 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> {
    
RequiresExpressionIndentation (RequiresExpressionIndentationKind) clang-format 16

用于 requires 表达式主体的缩进。

可能的值

  • REI_OuterScope (在配置中:OuterScope) 将 requires 表达式主体相对于 requires 表达式所在的外层作用域的缩进级别对齐。这是默认设置。

    template <typename T>
    concept C = requires(T t) {
      ...
    }
    
  • REI_Keyword (在配置中:Keyword) 将 requires 表达式主体相对于 requires 关键字对齐。

    template <typename T>
    concept C = requires(T t) {
                  ...
                }
    
SeparateDefinitionBlocks (SeparateDefinitionStyle) clang-format 14

指定是否使用空行来分隔定义块,包括类、结构体、枚举和函数。

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 {};
                                }

可能的值

  • SDS_Leave (在配置中:Leave) 保持定义块原样。

  • SDS_Always (在配置中:Always) 在定义块之间插入一个空行。

  • SDS_Never (在配置中:Never) 删除定义块之间的任何空行。

ShortNamespaceLines (Unsigned) clang-format 13

一个短命名空间跨越的未换行行的最大数量。默认为 1。

这通过计算未换行行(即既不包含打开也不包含关闭命名空间大括号的)来确定短命名空间的最大长度,并使 FixNamespaceComments 忽略为它们添加结束注释。

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
SkipMacroDefinitionBody (Boolean) clang-format 18

不要格式化宏定义主体。

SortIncludes (SortIncludesOptions) clang-format 3.8

控制 clang-format 是否以及如何排序 #includes

可能的值

  • SI_Never (在配置中:Never) 包含项从不排序。

    #include "B/A.h"
    #include "A/B.h"
    #include "a/b.h"
    #include "A/b.h"
    #include "B/a.h"
    
  • SI_CaseSensitive (在配置中:CaseSensitive) 包含项以 ASCII 顺序或区分大小写的方式排序。

    #include "A/B.h"
    #include "A/b.h"
    #include "B/A.h"
    #include "B/a.h"
    #include "a/b.h"
    
  • SI_CaseInsensitive (在配置中:CaseInsensitive) 包含项以字母顺序或不区分大小写的方式排序。

    #include "A/B.h"
    #include "A/b.h"
    #include "a/b.h"
    #include "B/A.h"
    #include "B/a.h"
    
SortJavaStaticImport (SortJavaStaticImportOptions) clang-format 12

在排序 Java 导入时,默认情况下静态导入放在非静态导入之前。如果 JavaStaticImportAfterImportAfter,则静态导入放在非静态导入之后。

可能的值

  • SJSIO_Before (在配置中:Before) 静态导入放在非静态导入之前。

    import static org.example.function1;
    
    import org.example.ClassA;
    
  • SJSIO_After (在配置中:After) 静态导入放在非静态导入之后。

    import org.example.ClassA;
    
    import static org.example.function1;
    
SortUsingDeclarations (SortUsingDeclarationsOptions) clang-format 5

控制 clang-format 是否以及如何排序 using 声明。

可能的值

  • SUD_Never (在配置中:Never) Using 声明从不排序。

    using std::chrono::duration_cast;
    using std::move;
    using boost::regex;
    using boost::regex_constants::icase;
    using std::string;
    
  • SUD_Lexicographic (在配置中:Lexicographic) Using 声明按以下定义的顺序排序:按 :: 拆分字符串并丢弃任何初始空字符串。按字典顺序排序名称列表,并在这些组内,名称按不区分大小写的字典顺序排列。

    using boost::regex;
    using boost::regex_constants::icase;
    using std::chrono::duration_cast;
    using std::move;
    using std::string;
    
  • SUD_LexicographicNumeric (在配置中:LexicographicNumeric) Using 声明按以下定义的顺序排序:按 :: 拆分字符串并丢弃任何初始空字符串。每个列表的最后一个元素是非命名空间名称;所有其他元素都是命名空间名称。按字典顺序排序名称列表,其中各个名称的排序顺序是所有非命名空间名称都位于所有命名空间名称之前,并且在这些组内,名称按不区分大小写的字典顺序排列。

    using boost::regex;
    using boost::regex_constants::icase;
    using std::move;
    using std::string;
    using std::chrono::duration_cast;
    
SpaceAfterCStyleCast (Boolean) clang-format 3.5

如果为 true,则在 C 样式强制转换后插入一个空格。

true:                                  false:
(int) i;                       vs.     (int)i;
SpaceAfterLogicalNot (Boolean) clang-format 9

如果为 true,则在逻辑非运算符(!)后插入一个空格。

true:                                  false:
! someExpression();            vs.     !someExpression();
SpaceAfterTemplateKeyword (Boolean) clang-format 4

如果为 true,则会在 template 关键字后插入一个空格。

true:                                  false:
template <int> void foo();     vs.     template<int> void foo();
SpaceAroundPointerQualifiers (SpaceAroundPointerQualifiersStyle) clang-format 12

定义在哪些情况下在指针限定符之前或之后放置空格

可能的值

  • SAPQ_Default (在配置中:Default) 不要确保指针限定符周围有空格,并使用 PointerAlignment 而不是。

    PointerAlignment: Left                 PointerAlignment: Right
    void* const* x = NULL;         vs.     void *const *x = NULL;
    
  • SAPQ_Before (在配置中:Before) 确保在指针限定符之前有一个空格。

    PointerAlignment: Left                 PointerAlignment: Right
    void* const* x = NULL;         vs.     void * const *x = NULL;
    
  • SAPQ_After (在配置中:After) 确保在指针限定符之后有一个空格。

    PointerAlignment: Left                 PointerAlignment: Right
    void* const * x = NULL;         vs.     void *const *x = NULL;
    
  • SAPQ_Both (在配置中:Both) 确保在指针限定符之前和之后都有一个空格。

    PointerAlignment: Left                 PointerAlignment: Right
    void* const * x = NULL;         vs.     void * const *x = NULL;
    
SpaceBeforeAssignmentOperators (Boolean) clang-format 3.7

如果为 false,则会在赋值运算符之前删除空格。

true:                                  false:
int a = 5;                     vs.     int a= 5;
a += 42;                               a+= 42;
SpaceBeforeCaseColon (Boolean) clang-format 12

如果为 false,则会在 case 冒号之前删除空格。

true:                                   false
switch (x) {                    vs.     switch (x) {
  case 1 : break;                         case 1: break;
}                                       }
SpaceBeforeCpp11BracedList (Boolean) clang-format 7

如果为 true,则会在用于初始化对象的 C++11 大括号列表之前(在前面的标识符或类型之后)插入一个空格。

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 };
SpaceBeforeCtorInitializerColon (Boolean) clang-format 7

如果为 false,则会在构造函数初始化冒号之前删除空格。

true:                                  false:
Foo::Foo() : a(a) {}                   Foo::Foo(): a(a) {}
SpaceBeforeInheritanceColon (Boolean) clang-format 7

如果为 false,则会在继承冒号之前删除空格。

true:                                  false:
class Foo : Bar {}             vs.     class Foo: Bar {}
SpaceBeforeJsonColon (Boolean) clang-format 17

如果为 true,则会在 JSON 冒号之前添加一个空格。对于其他语言,例如 JavaScript,请使用 SpacesInContainerLiterals 而不是。

true:                                  false:
{                                      {
  "key" : "value"              vs.       "key": "value"
}                                      }
SpaceBeforeParens (SpaceBeforeParensStyle) clang-format 3.5

定义在哪些情况下在左括号之前放置空格。

可能的值

  • SBPO_Never (在配置中:Never) 此选项已 **弃用**,并由下面的 Custom 选项取代,所有 SpaceBeforeParensOptions 选项都设置为了 false,除了 AfterPlacementOperator

  • SBPO_ControlStatements (在配置中:ControlStatements) 仅在控制语句关键字 (for/if/while...) 后面在左括号之前放置空格。

    void f() {
      if (true) {
        f();
      }
    }
    
  • SBPO_ControlStatementsExceptControlMacros (在配置中:ControlStatementsExceptControlMacros) 与 SBPO_ControlStatements 相同,但此选项不适用于 ForEach 和 If 宏。 这在 ForEach/If 宏被视为函数调用而不是控制语句的项目中很有用。 SBPO_ControlStatementsExceptForEachMacros 仍然是用于向后兼容的别名。

    void f() {
      Q_FOREACH(...) {
        f();
      }
    }
    
  • SBPO_NonEmptyParentheses (在配置中:NonEmptyParentheses) 仅当括号不为空时,在左括号之前放置空格。

    void() {
      if (true) {
        f();
        g (x, y, z);
      }
    }
    
  • SBPO_Always (在配置中:Always) 始终在左括号之前放置空格,除非语法规则禁止(在类似函数的宏定义中),或者由其他样式规则确定(在单目运算符、左括号等之后)。

    void f () {
      if (true) {
        f ();
      }
    }
    
  • SBPO_Custom (在配置中:Custom) 在 SpaceBeforeParensOptions 中配置每个单独的左括号前的空格。

SpaceBeforeParensOptions (SpaceBeforeParensCustom) clang-format 14

控制每个左括号前的空格。

如果 SpaceBeforeParens 设置为 Custom,请使用此选项来指定每个单独的左括号前的空格情况应如何处理。 否则,将忽略此选项。

# Example of usage:
SpaceBeforeParens: Custom
SpaceBeforeParensOptions:
  AfterControlStatements: true
  AfterFunctionDefinitionName: true

嵌套配置标志

精确控制左括号前的空格。

# Should be declared this way:
SpaceBeforeParens: Custom
SpaceBeforeParensOptions:
  AfterControlStatements: true
  AfterFunctionDefinitionName: true
  • bool AfterControlStatements 如果为 true,则在控制语句关键字 (for/if/while…) 和左括号之间放置空格。

    true:                                  false:
    if (...) {}                     vs.    if(...) {}
    
  • bool AfterForeachMacros 如果为 true,则在 foreach 宏和左括号之间放置空格。

    true:                                  false:
    FOREACH (...)                   vs.    FOREACH(...)
      <loop-body>                            <loop-body>
    
  • bool AfterFunctionDeclarationName 如果为 true,则在函数声明名称和左括号之间放置空格。

    true:                                  false:
    void f ();                      vs.    void f();
    
  • bool AfterFunctionDefinitionName 如果为 true,则在函数定义名称和左括号之间放置空格。

    true:                                  false:
    void f () {}                    vs.    void f() {}
    
  • bool AfterIfMacros 如果为 true,则在 if 宏和左括号之间放置空格。

    true:                                  false:
    IF (...)                        vs.    IF(...)
      <conditional-body>                     <conditional-body>
    
  • bool AfterOverloadedOperator 如果为 true,则在运算符重载和左括号之间放置空格。

    true:                                  false:
    void operator++ (int a);        vs.    void operator++(int a);
    object.operator++ (10);                object.operator++(10);
    
  • bool AfterPlacementOperator 如果为 true,则在运算符 new/delete 和左括号之间放置空格。

    true:                                  false:
    new (buf) T;                    vs.    new(buf) T;
    delete (buf) T;                        delete(buf) T;
    
  • bool AfterRequiresInClause 如果为 true,则在 requires 子句中的 requires 关键字和左括号之间放置空格(如果有)。

    true:                                  false:
    template<typename T>            vs.    template<typename T>
    requires (A<T> && B<T>)                requires(A<T> && B<T>)
    ...                                    ...
    
  • bool AfterRequiresInExpression 如果为 true,则在 requires 表达式中的 requires 关键字和左括号之间放置空格。

    true:                                  false:
    template<typename T>            vs.    template<typename T>
    concept C = requires (T t) {           concept C = requires(T t) {
                  ...                                    ...
                }                                      }
    
  • bool BeforeNonEmptyParentheses 如果为 true,则仅当括号不为空时在左括号之前放置空格。

    true:                                  false:
    void f (int a);                 vs.    void f();
    f (a);                                 f();
    
SpaceBeforeRangeBasedForLoopColon (Boolean) clang-format 7

如果为 false,则将在基于范围的 for 循环冒号之前删除空格。

true:                                  false:
for (auto v : values) {}       vs.     for(auto v: values) {}
SpaceBeforeSquareBrackets (Boolean) clang-format 10

如果为 true,则将在 [ 之前放置空格。 lambda 表达式不会受到影响。 只有第一个 [ 会添加空格。

true:                                  false:
int a [5];                    vs.      int a[5];
int a [5][5];                 vs.      int a[5][5];
SpaceInEmptyBlock (Boolean) clang-format 10

如果为 true,则将在 {} 中插入空格。

true:                                false:
void f() { }                   vs.   void f() {}
while (true) { }                     while (true) {}
SpaceInEmptyParentheses (Boolean) clang-format 3.7

如果为 true,则可能会在 () 中插入空格。 此选项已 **弃用**。 请参阅 SpacesInParensOptionsInEmptyParentheses

SpacesBeforeTrailingComments (Unsigned) clang-format 3.7

在尾随行注释 (// - 注释) 之前放置的空格数。

这不会影响尾随块注释 (/* - 注释),因为这些注释通常具有不同的使用模式和许多特殊情况。 在 Verilog 的情况下,它不会影响模块头中开括号后面的注释,因为该注释可能是针对下一行的端口,而不是它所跟随的括号。

SpacesBeforeTrailingComments: 3
void f() {
  if (true) {   // foo1
    f();        // bar
  }             // foo
}
SpacesInAngles (SpacesInAnglesStyle) clang-format 3.4

用于模板参数列表的 SpacesInAnglesStyle。

可能的值

  • SIAS_Never (在配置中:Never) 在 < 之后和 > 之前删除空格。

    static_cast<int>(arg);
    std::function<void(int)> fct;
    
  • SIAS_Always (在配置中:Always) 在 < 之后和 > 之前添加空格。

    static_cast< int >(arg);
    std::function< void(int) > fct;
    
  • SIAS_Leave (在配置中:Leave) 如果存在任何空格,则在 < 之后和 > 之前保留单个空格。 选项 Standard: Cpp03 优先。

SpacesInCStyleCastParentheses (Boolean) clang-format 3.7

如果为 true,则可能会在 C 样式强制转换中插入空格。 此选项已 **弃用**。 请参阅 SpacesInParensOptionsInCStyleCasts

SpacesInConditionalStatement (Boolean) clang-format 10

如果为 true,则将在 if/for/switch/while 条件周围插入空格。 此选项已 **弃用**。 请参阅 SpacesInParensOptionsInConditionalStatements

SpacesInContainerLiterals (Boolean) clang-format 3.7

如果为 true,则会在容器文字 (例如 ObjC 和 Javascript 数组和字典文字) 内部插入空格。 对于 JSON,请改用 SpaceBeforeJsonColon

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});
SpacesInLineCommentPrefix (SpacesInLineComment) clang-format 13

在行注释的开头允许多少个空格。 要禁用最大值,请将其设置为 -1,除此之外,最大值优先于最小值。

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

请注意,在线注释部分,将保留后续行的相对缩进,这意味着以下内容

before:                                   after:
Minimum: 1
//if (b) {                                // if (b) {
//  return true;                          //   return true;
//}                                       // }

Maximum: 0
/// List:                                 ///List:
///  - Foo                                /// - Foo
///    - Bar                              ///   - Bar

此选项仅在 ReflowComments 设置为 true 时有效。

嵌套配置标志

控制单个行注释中的空格。

  • unsigned Minimum 注释开头的最小空格数。

  • unsigned Maximum 注释开头的最大空格数。

SpacesInParens (SpacesInParensStyle) clang-format 17

定义在哪些情况下将在 ( 之后和 ) 之前插入空格。

可能的值

  • SIPO_Never (在配置中:Never) 不要在括号中放置空格。

    void f() {
      if(true) {
        f();
      }
    }
    
  • SIPO_Custom(在配置中:Custom)在 SpacesInParensOptions 中配置每个括号内的空格。

SpacesInParensOptions (SpacesInParensCustom) clang-format 17

控制括号内单个空格。

如果 SpacesInParens 设置为 Custom,请使用此选项指定如何处理括号内每个空格情况。否则,此选项将被忽略。

# Example of usage:
SpacesInParens: Custom
SpacesInParensOptions:
  ExceptDoubleParentheses: false
  InConditionalStatements: true
  InEmptyParentheses: true

嵌套配置标志

精确控制括号内的空格。

# Should be declared this way:
SpacesInParens: Custom
SpacesInParensOptions:
  ExceptDoubleParentheses: false
  InConditionalStatements: true
  Other: true
  • bool ExceptDoubleParentheses 覆盖以下任何选项,以防止在左右括号都使用多个括号时添加空格。

     true:
     __attribute__(( noreturn ))
     __decltype__(( x ))
     if (( a = b ))
    false:
      Uses the applicable option.
    
  • bool InConditionalStatements 仅在条件语句 (for/if/while/switch...) 内的括号中添加空格。

    true:                                  false:
    if ( a )  { ... }              vs.     if (a) { ... }
    while ( i < 5 )  { ... }               while (i < 5) { ... }
    
  • bool InCStyleCasts 在 C 样式强制转换中添加空格。

    true:                                  false:
    x = ( int32 )y                  vs.    x = (int32)y
    y = (( int (*)(int) )foo)(x);          y = ((int (*)(int))foo)(x);
    
  • bool InEmptyParentheses 在空括号 (()) 中插入空格。

    true:                                false:
    void f( ) {                    vs.   void f() {
      int x[] = {foo( ), bar( )};          int x[] = {foo(), bar()};
      if (true) {                          if (true) {
        f( );                                f();
      }                                    }
    }                                    }
    
  • bool Other 在未被前面选项覆盖的括号中添加空格。

    true:                                 false:
    t f( Deleted & ) & = delete;    vs.   t f(Deleted &) & = delete;
    
SpacesInParentheses (Boolean) clang-format 3.7

如果 true,将在 ( 之后和 ) 之前插入空格。此选项已弃用。通过使用 SpacesInParens 以及 Custom,并将所有 SpacesInParensOptions 设置为 trueInCStyleCastsInEmptyParentheses 除外),可以保留之前的行为。

SpacesInSquareBrackets (Boolean) clang-format 3.7

如果 true,将在 [ 之后和 ] 之前插入空格。无参数的 lambda 或未指定大小的数组声明不受影响。

true:                                  false:
int a[ 5 ];                    vs.     int a[5];
std::unique_ptr<int[]> foo() {} // Won't be affected
Standard (LanguageStandard) clang-format 3.7

解析和格式化与此标准兼容的 C++ 结构。

c++03:                                 latest:
vector<set<int> > x;           vs.     vector<set<int>> x;

可能的值

  • LS_Cpp03(在配置中:c++03)以 C++03 的方式解析和格式化。 Cpp03c++03 的已弃用别名。

  • LS_Cpp11(在配置中:c++11)以 C++11 的方式解析和格式化。

  • LS_Cpp14(在配置中:c++14)以 C++14 的方式解析和格式化。

  • LS_Cpp17(在配置中:c++17)以 C++17 的方式解析和格式化。

  • LS_Cpp20(在配置中:c++20)以 C++20 的方式解析和格式化。

  • LS_Latest(在配置中:Latest)使用最新支持的语言版本解析和格式化。 Cpp11Latest 的已弃用别名。

  • LS_Auto(在配置中:Auto)根据输入自动检测。

StatementAttributeLikeMacros (List of Strings) clang-format 12

在语句前面忽略的宏,就像它们是属性一样。这样它们就不会被解析为标识符,例如,用于 Qts emit。

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.
StatementMacros (List of Strings) clang-format 8

应该被解释为完整语句的宏向量。

典型的宏是表达式,需要添加分号;有时情况并非如此,这允许 clang-format 了解这种情况。

例如:Q_UNUSED

TabWidth (Unsigned) clang-format 3.7

用于制表符停止的列数。

TableGenBreakInsideDAGArg (DAGArgStyle) clang-format 19

TableGen 中 DAGArg 内换行的样式。

可能的值

  • DAS_DontBreak(在配置中:DontBreak)从不换行 DAGArg 内。

    let DAGArgIns = (ins i32:$src1, i32:$src2);
    
  • DAS_BreakElements(在配置中:BreakElements)在 DAGArg 内每个列表元素(最后一个除外)后换行。这与第一个元素对齐。

    let DAGArgIns = (ins i32:$src1,
                         i32:$src2);
    
  • DAS_BreakAll(在配置中:BreakAll)在 DAGArg 内运算符和所有元素之后换行。

    let DAGArgIns = (ins
        i32:$src1,
        i32:$src2
    );
    
TableGenBreakingDAGArgOperators (List of Strings) clang-format 19

仅当 TableGenBreakInsideDAGArg 不是 DontBreak 时有效。字符串列表需要由 TableGen 中的标识符组成。如果指定了任何标识符,这将限制 TableGenBreakInsideDAGArg 选项对以指定标识符开头的 DAGArg 值的换行。

例如,配置:

TableGenBreakInsideDAGArg: BreakAll
TableGenBreakingDAGArgOperators: [ins, outs]

使得换行仅发生在以指定标识符 insouts 开头的 DAGArg 内。

let DAGArgIns = (ins
    i32:$src1,
    i32:$src2
);
let DAGArgOtherID = (other i32:$other1, i32:$other2);
let DAGArgBang = (!cast<SomeType>("Some") i32:$src1, i32:$src2)
TemplateNames (List of Strings) clang-format 20

应该被解释为模板名的非关键字标识符向量。

模板名后面的 < 被注释为模板打开符,而不是二元运算符。

TypeNames (List of Strings) clang-format 17

应该被解释为类型名的非关键字标识符向量。

类型名和另一个非关键字标识符之间的 *&&& 被注释为指针或引用标记,而不是二元运算符。

TypenameMacros (List of Strings) clang-format 9

应该被解释为类型声明,而不是函数调用的宏向量。

这些宏应该具有以下形式:

STACK_OF(...)

在 .clang-format 配置文件中,可以像这样配置它

TypenameMacros: [STACK_OF, LIST]

例如:OpenSSL STACK_OF、BSD LIST_ENTRY。

UseCRLF (Boolean) clang-format 10

此选项已弃用。请参阅 LineEndingLFCRLF

UseTab (UseTabStyle) clang-format 3.7

在结果文件中使用制表符的方式。

可能的值

  • UT_Never(在配置中:Never)从不使用制表符。

  • UT_ForIndentation(在配置中:ForIndentation)仅将制表符用于缩进。

  • UT_ForContinuationAndIndentation(在配置中:ForContinuationAndIndentation)用制表符填充所有前导空格,并将空格用于出现在一行中的对齐(例如,连续的赋值和声明)。

  • UT_AlignWithSpaces(在配置中:AlignWithSpaces)将制表符用于行延续和缩进,并将空格用于对齐。

  • UT_Always(在配置中:Always)只要需要填充跨越至少一个制表符停止到下一个制表符停止的空格,就使用制表符。

VerilogBreakBetweenInstancePorts (Boolean) clang-format 17

对于 Verilog,在模块实例化中将每个端口放在单独的一行。

true:
ffnand ff1(.q(),
           .qbar(out1),
           .clear(in1),
           .preset(in2));

false:
ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));
WhitespaceSensitiveMacros (List of Strings) clang-format 11

对空格敏感并且不应被修改的宏向量。

这些宏应该具有以下形式:

STRINGIZE(...)

在 .clang-format 配置文件中,可以像这样配置它

WhitespaceSensitiveMacros: [STRINGIZE, PP_STRINGIZE]

例如:BOOST_PP_STRINGIZE

添加额外的样式选项

每个额外的样式选项都会给 clang-format 项目增加成本。其中一些成本会影响 clang-format 自身的开发,因为我们需要确保任何给定的选项组合都可以正常工作,并且新功能不会以任何方式破坏任何现有的选项。对于最终用户来说,也会有成本,因为选项变得难以发现,人们必须考虑并决定他们并不真正关心的选项。

clang-format 项目的目标更多地是很好地支持有限的样式集,而不是支持野外代码库中使用的所有样式。当然,我们希望支持所有主要的项目,因此为添加样式选项建立了以下标准。每个新的样式选项必须

  • 被用于一个规模相当大的项目(拥有数十位贡献者)

  • 有一个公开可访问的样式指南

  • 有人愿意贡献和维护补丁

示例

类似于 Linux 内核样式 的样式

BasedOnStyle: LLVM
IndentWidth: 8
UseTab: Always
BreakBeforeBraces: Linux
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false

结果是(想象一下这里使用制表符进行缩进)

void test()
{
        switch (x) {
        case 0:
        case 1:
                do_something();
                break;
        case 2:
                do_something_else();
                break;
        default:
                break;
        }
        if (condition)
                do_something_completely_different();

        if (x == y) {
                q();
        } else if (x > y) {
                w();
        } else {
                r();
        }
}

类似于默认的 Visual Studio 格式化样式

UseTab: Never
IndentWidth: 4
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 0

结果是

void test()
{
    switch (suffix)
    {
    case 0:
    case 1:
        do_something();
        break;
    case 2:
        do_something_else();
        break;
    default:
        break;
    }
    if (condition)
        do_something_completely_different();

    if (x == y)
    {
        q();
    }
    else if (x > y)
    {
        w();
    }
    else
    {
        r();
    }
}