clang-format BinPackArguments не работает должным образом

clang-format имеет 2 варианта: BinPackParameters и BinPackArguments. Кажется, что они контролируют отступ в объявлениях функций и вызовах функций.

BinPackParameters, похоже, обеспечивает ожидаемый результат для объявления функции, но BinPackArguments, похоже, не работает так, как можно было бы ожидать от вызова функции.

Вот простой тестовый файл:

#include <stdbool.h>

void function_with_a_huge_name_that_should_just_not_be(unsigned int a, char *b, unsigned int c, unsigned int d, unsigned int e)
{
    return;
}

int main()
{
    function_with_a_huge_name_that_should_just_not_be(13, "bb", 1234234, 4324324, 2355345);
}

А вот как он форматируется:

#include <stdbool.h>

void function_with_a_huge_name_that_should_just_not_be(unsigned int a,
    char *b,
    unsigned int c,
    unsigned int d,
    unsigned int e)
{
    return;
}

int main()
{
    function_with_a_huge_name_that_should_just_not_be(
        13, "bb", 1234234, 4324324, 2355345);
}

Мой .clang-format файл выглядит следующим образом:

---
AccessModifierOffset: -2
AlignAfterOpenBracket: false
AlignEscapedNewlinesLeft: false
AlignOperands:   true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackParameters: false
BinPackArguments: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit:     80
CommentPragmas:  '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
IndentCaseLabels: false
IndentWidth:     4
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language:        Cpp
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles:  false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard:        Auto
TabWidth:        4
UseTab:          Never

Моя версия в формате clang: 3.6.0 (tags/RELEASE_360/final)

Когда и BinPackParameters, и BinPackArguments ложны, я ожидал бы получить такой же отступ для вызова функции, как и для объявления функции.

Есть идеи, что я делаю неправильно?


person Lefteris    schedule 05.05.2015    source источник


Ответы (3)


Я не думаю, что вы делаете что-то не так. Что происходит, так это то, что clang-format понимает, что строка, в которой вы вызываете функцию, длиннее, чем предел вашего столбца (80 символов в ваших настройках). Ваш AlignAfterOpenBracket установлен в false, поэтому clang-format помещает аргументы в новую строку (обратите внимание, что AlignAfterOpenBracket получил дополнительные возможности в более поздних версиях clang-format).

Вы установили для обоих параметров BinPack... значение false, однако есть дополнительный параметр, который управляет объявлением функции и вызовом функции, AllowAllParametersOfDeclarationOnNextLine (в вашем примере установлено значение false). Для объявления функции это приведет к тому, что все параметры будут находиться в отдельных строках, если они не помещаются в той же строке, что и имя функции. Для вызова функции нет соответствующей настройки.

В вашем случае аргументы, которые вы даете функции, помещаются в следующую строку после имени функции. Длина второй строки ‹80, поэтому clang-format ничего с ней не делает. Если бы строка аргументов была бы длиннее, чем предел вашего столбца, clang-format поместил бы их в отдельные строки.

Итак, ответ таков: начиная с версии 3.9, нет возможности настроить clang-format для размещения каждого аргумента в отдельной строке, если они помещаются в одну строку.

person villintehaspam    schedule 17.01.2016

Попробуйте установить ColumnLimit в 0. Похоже, что этот параметр «переопределяет» или имеет более высокий приоритет по сравнению с параметрами BinPackParameters и BinPackArguments.

person Konstantin    schedule 15.05.2015
comment
Спасибо, но с ColumnLimit 0 стиль не изменился, так как ни одна строка не может считаться слишком большой, чтобы ее можно было сломать. - person Lefteris; 16.05.2015
comment
Это действительно сработало для меня. Предел столбца, равный 0, означает, что ограничения по столбцу нет. В этом случае clang-format будет учитывать решения о переносе строк внутри операторов, если они не противоречат другим правилам. clang.llvm.org/docs/ClangFormatStyleOptions.html - person cs01; 26.10.2017
comment
Есть ли исправление? Я также поместил ошибку в LLVM по поводу этой проблемы, потому что я не могу использовать clang-format с этой ужасной ошибкой: bugs.llvm.org/show_bug.cgi?id=35968 - person Taw; 22.01.2018

Параметры BinPack *, установленные в false, заставят параметры / аргументы быть либо в одной строке, либо каждый в отдельной строке. Допускаются оба случая, но не смешивание, например. два параметра в одной строке, а остальные в другой строке не допускается.

Кажется, что clang-format выбирает формат «все на одной строке» и «каждый на отдельной строке» индивидуально для каждого случая.

person boorg    schedule 16.12.2015