数学表达式中奇怪的铿锵格式 我想知道如何解决我在代码< CLAN格式< /C> >和C++中的较长数学表达式时遇到的奇怪问题。假设我们在test.h中保存了以下示例代码: void TestFunction() { int long_int_variable_name = 1; int result = (long_int_variable_name + long_int_variable_name) * long_int_variable_name - 1; }
我们可以通过以下操作将其格式化为谷歌风格:数学表达式中奇怪的铿锵格式 我想知道如何解决我在代码< CLAN格式< /C> >和C++中的较长数学表达式时遇到的奇怪问题。假设我们在test.h中保存了以下示例代码: void TestFunction() { int long_int_variable_name = 1; int result = (long_int_variable_name + long_int_variable_name) * long_int_variable_name - 1; },c++,clang-format,C++,Clang Format,我们可以通过以下操作将其格式化为谷歌风格: clang-format -style=google -dump-config > .clang-format clang-format -i -style=file test.h 这将为结果产生一个格式相当笨拙的表达式: void TestFunction() { int long_int_variable_name = 1; int result = (long_int_variable_name + long_int_variab
clang-format -style=google -dump-config > .clang-format
clang-format -i -style=file test.h
这将为结果产生一个格式相当笨拙的表达式:
void TestFunction() {
int long_int_variable_name = 1;
int result = (long_int_variable_name + long_int_variable_name) *
long_int_variable_name -
1;
}
它看起来像是在乘法的第二个操作数之前添加了一个行连续缩进,但在减法的第二个操作数之前对齐了行的开头。除此之外,为什么它甚至把1
降到了一个新行?看起来它试图根据数学优先级直观地将操作数耦合得更紧/更松,但这太过分了
所以这里的主要问题是
- 为什么clang决定用一种看起来很尴尬的方式格式化它
- 如何使这种类型的表达式的格式更清晰,或者可以使用哪些选项使其看起来更合理李>
我认为,只有当代码的其余部分无法放入当前行时,行才会中断,这将是一个很好的起点。之后,决定缩进的位置有助于改进它
简短而肮脏的回答:在这种情况下,有一个技巧是有效的
如果您不喜欢这样,请为中间计算结果命名
这个答案来自哪里?有更好的答案吗?
通过一些实验,我们可以发现clang在这里做什么。让我们比较对齐操作数:true
与false
:
// AlignOperands: true
{
int result = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *
cccccccccccccccccccccccccccccccccc -
d;
}
// AlignOperands: false
{
int result = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *
cccccccccccccccccccccccccccccccccc -
d;
}
// Note: these examples use IndentWidth: 4, ContinuationIndentWidth: 8
在这两种情况下,要乘法的第二个操作数的缩进比要加法的第二个操作数的缩进多。所以看起来clang试图表达一个事实,乘法比加法结合得更紧密。这其实不是什么问题
这里的问题是d
被放在它自己的行上。为什么?
似乎clangformat
已经决定,由于加法的第一个操作数跨越多行,因此在第二个操作数之后必须有一个换行符。因为乘法的第二个操作数有一个额外的缩进,所以看起来很奇怪
在中搜索“操作数”、“缩进”、“优先级”、“乘法”等不会显示任何相关选项。这给我们留下了两种可能的方法
选项1:找到一些创造性的技巧来编写代码,这样铿锵格式就不会把它弄糟。在这种情况下,切换求和的顺序是关键:
{
int result = -d + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *
cccccccccccccccccccccccccccccccccc;
}
不幸的是,现在我们正在根据我们的格式化工具做出代码编写决策,这是一种倒退并导致混乱(自然的问题是:为什么它是-d+x
而不是更简单的x-d
?)
选项2:另一个增加代码可读性的额外好处是为计算的中间结果创建名称。例如:
{
double revenue = price_per_unit * num_units_sold;
double profit = revenue - cost;
}
这真的可以帮助读者,否则他们会问,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
默认选项:最后一个选项是在相关代码块周围添加clangformat off
,clangformat on
注释。我不太喜欢这一点,因为它给源代码添加了很多混乱(2行ON/OFF,加上另一行解释为什么要关闭它),但它始终是一个基于上下文考虑的选项。你可以找到所有的,这样你就可以编写自己的<代码> .ClangFrase< /Cl>文件来获得你想要的任何行为。(在工具的能力范围内)。您已经阅读了文档吗?如果没有,请阅读。您阅读了文档吗?是的。当然。详细。多次。我们在我的工作场所使用了clang格式,并且我们的。clang格式
文件经过了多次修订和审查,我是它的主要作者。如果我没有仔细阅读文档,我将疏忽大意一般来说,一个简单的格式化规则(像这样)对于处理困难的代码是很有帮助的,即使对于您所展示的简单代码示例来说,它看起来有些过分。看起来“不错”的代码格式化从长远来看,对于简单的代码来说是误导性的,但是对于复杂的代码来说是不太有用的对于简单的代码,但也有助于理解更复杂的代码,然后自己编写规则。你会发现编写格式规则本身要复杂得多。阅读文档是一件非常痛苦的事情:只需花3个小时就可以完成一次。如果有5分钟的时间回答堆栈溢出问题,而我不是其中之一配置.clang格式的文档,我会在任何一天都把它放在阅读文档的上面。我现在几乎读完了文档…所以回到它。。。
{
double revenue = price_per_unit * num_units_sold;
double profit = revenue - cost;
}