1. 缩进

IndentWidth,缩进宽度。Google 默认是 2,通常我们设置为 4
注意:需要先将 IndentWidth 设置为 4,否则后面设置会有问题。

1.1 缩进2

  • IndentWidth: 2
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> v = {1, 2, 3, 4, 5};

  for ( int n : v ) {
    if ( n % 2 == 0 ) {
      std::cout << "even: " << n << '\n';
    } else {
      std::cout << "odd:  " << n << '\n';
    }
  }

  return 0;
}

1.2 缩进4

  • IndentWidth: 4
#include <iostream>
#include <vector>

int main ()
{
    std::vector<int> v = {1, 2, 3, 4, 5};

    for ( int n : v ) {
        if ( n % 2 == 0 ) {
            std::cout << "even: " << n << '\n';
        } else {
            std::cout << "odd:  " << n << '\n';
        }
    }

    return 0;
}

2. 访问修饰符的偏移

AccessModifierOffset,访问修饰符(publicprivate 等)的偏移,通常设置为 -4

  • 效果一(AccessModifierOffset: -4
#include <string>

class Person {
public:
    Person ();

private:
    std::string name;
    int         age;
};
  • 效果二 (AccessModifierOffset: -1
#include <string>

class Person {
   public:
    Person ();

   private:
    std::string name;
    int         age;
};

3. 最大的空行数

MaxEmptyLinesToKeep,最多保留多少个连续空行(Unsigned

  • 效果一(MaxEmptyLinesToKeep: 1

任意空行之间的空格数 > 1 时,会被压缩为 1 行

void f () {
    int a;
    int b;

    a = 1;

    b = 2;
}
  • 效果二(MaxEmptyLinesToKeep: 2

任意空行之间的空格数 > 2 时,会被压缩为 2 行

void f () {
    int a;
    int b;

    a = 1;


    b = 2;
}

4. 函数内首行留空

KeepEmptyLinesKeepEmptyLinesStyle)用于精细控制哪些位置的空行应该被保留。

它包含若干子选项,常用的有:

  • AtEndOfFile:是否保留文件末尾的空行(true / false
  • AtStartOfBlock:是否保留块({ ... })开头的空行
  • AtStartOfFile:是否保留文件开头的空行(true / false

说明:KeepEmptyLines 只决定哪些位置的空行被允许保留,保留的数量MaxEmptyLinesToKeep 控制。

手写代码如下:

#include <iostream>

int main () {
    
    int a = 10;
    int b = 20;

    std::cout << (a + b) << std::endl;

    return 0;
}

4.1 格式化效果1

  • AtStartOfBlock: false
#include <iostream>

int main () {
    int a = 10;
    int b = 20;

    std::cout << (a + b) << std::endl;

    return 0;
}

4.2 格式化效果2

  • AtStartOfBlock: true
#include <iostream>

int main () {
    
    int a = 10;
    int b = 20;

    std::cout << (a + b) << std::endl;

    return 0;
}

5. 每行最多字符数

ColumnLimit,列宽限制,控制在何处尝试换行(Unsigned
默认值为 80(若未在 .clang-format 中明确设置,clang-format 默认为 80
如果团队使用较宽显示器或大多数文件为长模板/表达式,建议 100–120

6. 头文件排序

SortIncludes,按规则对 #include 语句排序(并可合并/分组),提高包含顺序的一致性与可读性。

SortIncludes:
  Enabled: true                        # 是否使能排序
  IgnoreCase: false                    # 忽略大小写

# Preserve:保留每个 include block(被空行或代码分隔的块)为单位,只在每个块内排序。
# Merge:把多个块合并成一个块再排序(不按类别拆分)。
# Regroup:先合并所有块,再根据 IncludeCategories 的分类和优先级分组、排序
IncludeBlocks:   Regroup   
            
IncludeCategories:
  # 匹配:<iostream>, <vector>, <boost/algorithm>
  # Priority,越小越先放在前面(形成分组顺序)
  - Regex:           '^<[^.]*>'        
    Priority:        1
   
  # 匹配:<zlib.h>, <sys/types.h>, <ext/foo.h>
  - Regex:           '^<.*\.h>'        
    Priority:        2
    
  # 兜底规则,匹配任何字符串(会匹配所有未被前面规则捕获的 includes)。
  # 通常会捕获:被双引号包裹的头 "my.h"、以及所有其它未被前两条匹配到的 include。
  # 注意:因为它非常宽泛,应放在最后
  - Regex:           '.*'
    Priority:        3
  • 手写
#include <vector>
#include <iostream>
#include "my.h"
#include <zlib.h>
#include <ext/foo.h>
  • 格式化
#include <iostream>
#include <vector>

#include <ext/foo.h>
#include <zlib.h>

#include "my.h"

7. 临时禁用

使用 clang-format 格式化代码,在团队内统一代码风格的确很方便
但有一些代码,我们并不想让 clang-format 调整格式,这时可以使用注释临时禁用 clang-format,如下:

  • 手写
#include <iostream>

int main () {
    int a=10; 

    // clang-format off
    long  b=20;
    // clang-format on

    std::cout<<"format\n";

    /* clang-format off */
    std::cout<<"no format\n";
    /* clang-format on */

    return 0;
}
  • 格式化
#include <iostream>

int main () {
    int a = 10;

    // clang-format off
    long  b=20;
    // clang-format on

    std::cout << "no format\n";

    /* clang-format off */
    std::cout<<"no format\n";
    /* clang-format on */

    return 0;
}