clang格式化器能否为单行if语句等添加大括号

79

clang-format是否有选项可以为所有if()/do/while语句等添加大括号?

例如:

if( i == 42 )
   std::cout << "You found the meaning of life\n";
else
   std::cout << "Wrong!\n";

if( i == 42 )
{
   std::cout << "You found the meaning of life\n";
}
else
{
   std::cout << "Wrong!\n";
}

使用

$ clang-format --version
clang-format version 3.6.0

2
我在快速浏览Clang-Format Style Options时没有找到任何选项。 - Baum mit Augen
2
@BaummitAugen 我也无法理解 - 但是我认为某些选项的描述非常模糊。 - Adrian Cornish
请参考此答案,了解一种在没有大括号的情况下搜索常见单行的方法。 - Richard
1
你简直无法想象。他们格式化所有的东西......除了这个。 - user997112
2个回答

45

使用FIXITS,clang-tidy可以对您的代码进行语法更改。

clang-tidy YOUR_FILE.cpp -fix -checks="readability-braces-around-statements" -- COMPILE_OPTIONS

更新:

对于这个问题,clang-tidy是一个比较耗费资源的工具,因为它需要编译选项来解析文件。不幸的是,clang-format(截至v3.9)不会添加大括号。

COMPILE_OPTIONS将包括您用于编译文件的包含路径等信息,例如 -std=c++14 -stdlib=libc++ -O2 -I.

如果您从CMake获取了一个 compile_options.json 文件,则可以将其所在目录的路径传递给clang-tidy,并且它将查找文件的相应编译选项:

clang-tidy YOUR_FILE.cpp -fix -checks="readability-braces-around-statements" -p COMPILE_OPTIONS_DIR

2
有没有可能在不创建编译数据库的情况下运行它?比如说,我只想运行可读性检查,而不是查找编译错误。我这么问是因为我想独立于整个项目编辑单个文件。当我尝试这样做时,我会得到“尝试加载编译数据库时出错”和“无标志运行”的错误提示。我认为这是因为它忽略了可读性检查,因为它没有像我希望的那样添加大括号。 - Novice C
举一个具体例子,假设我的文件有 #include "../header.h",但我正在一个没有父目录中的header.h的目录中编辑该文件。在这种情况下,是否仍然可以使用clang-tidy呢? - Novice C
我已经更新了我的答案,并添加了额外的信息,因为它无法适应评论框。 - jbcoe
clang-tidy只是静态分析器的一个前端,它真的需要成为您构建过程的一部分。 - Droopycom
@jbcoe 打卡,截至 clang-format 7.0 版本,它仍然无法添加大括号吗? - Tyler Shellberg
显示剩余2条评论

23
从clang-format-15(目前的trunk)开始,答案是肯定的-使用新的InsertBraces选项,该选项刚刚在今天推出:
https://github.com/llvm/llvm-project/commit/77e60bc42c48e16d646488d43210b1630cd4db49 https://reviews.llvm.org/D120217 来自clang-format 文档

InsertBraces (Boolean) clang-format 15

在C++中的控制语句(if、else、for、do和while)后插入大括号,除非控制语句位于宏定义内或者大括号将包含预处理器指令。

警告:

将此选项设置为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);

1
有趣 - 我想拉取并构建它以尝试一下 - 我想知道它是否比clang-tidy更好地处理#defines。clang-tidy总是把这个搞砸:if(x==y) #ifdef OS1 z=103 #else z=-23 #endif只是在我提问8年后才实现 ;-) - Adrian Cornish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接