如何使用 clang 格式保持标签缩进?

How to keep label indentation with clang-format?

Clang 格式删除了 goto 标签上的缩进。不推荐使用 // clang-format off。如何配置 clang-format 以不更改配置文件中标签的缩进?

期望输出

标签缩进以匹配函数中的代码。他们应该留在那个缩进中。

int new_foo(foo **bar) {

  *bar = malloc(sizeof(foo));
  if ( !bar ) {
    goto failed;
  }

  goto done;
  failed: {
    return -1;
  }
  done:
  return 1;
}

实际输出

这就是 clang-format 实际产生的结果。这是不可取的,因为它会破坏缩进折叠。

int new_foo(foo **bar) {

  *bar = malloc(sizeof(foo));
  if ( !bar ) {
    goto failed;
  }

  goto done;
failed: {
  return -1;
}
done:
  return 1;
}

更新

.clang-format 配置中使用 IndentGotoLabels: false(或 true)时,这就是结果。请注意 done:failed: 标签向左移动。

int new_foo(foo **bar) {
  *bar = malloc(sizeof(foo));
  if (!bar) {
    goto failed;
  }

  goto done;
failed : { return -1; }
done:
  return 1;
}

.clang-format 的内容。

IndentGotoLabels: false

命令 cat test.cc | clang-format 和 运行 在 .clang-format 所在的同一目录中。

编辑:我最初的回答是错误的。

看起来无论 IndentGotoLabels 是如何设置的,goto 标签都没有缩进到与代码相同的级别。考虑以下代码片段:

int new_foo()
{
    {
        int *p = malloc(sizeof(int));
        if (!p)
            goto first_label;

        int *q = malloc(sizeof(int));
        if (!q)
            goto second_label;

        return 0;

        first_label:
        return 1;
    }

    second_label:
    return 2;
}

使用以下配置:

---
Language:        Cpp
IndentGotoLabels: false
TabWidth: 4
...

运行 clang-format 会给我们:

int new_foo() {
  {
    int *p = malloc(sizeof(int));
    if (!p)
      goto first_label;

    int *q = malloc(sizeof(int));
    if (!q)
      goto second_label;

    return 0;

first_label:
    return 1;
  }

second_label:
  return 2;
}

如果我们将 IndentGotoLabels 更改为 true 我们有:

int new_foo() {
  {
    int *p = malloc(sizeof(int));
    if (!p)
      goto first_label;

    int *q = malloc(sizeof(int));
    if (!q)
      goto second_label;

    return 0;

  first_label:
    return 1;
  }

second_label:
  return 2;
}

标签现在缩进了,但与开始代码块的 { 处于同一级别,而不是代码本身。

我不知道这是 clang-format 做不到的,还是我缺少一些选项。即使它没有真正解决问题,我也会保留我的答案。它可能会被证明是有用的。

这也是记录在案的行为,如果我们查看文档中的示例,可能无法更改它。

这属于意见领域,但 clang-format 有时可能非常有限。如果您可以自由使用其他代码格式化程序 astyle 可能会用 --indent-labels.

做您想做的事

初步回答:

.clang-format 文件中将 IndentGotoLabels 设置为 false。有关详细信息,请参阅 the documentation

如果您没有 .clang-format 文件,您可以根据预定义的样式生成一个:

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