Break after operator=( in clang-format

Viewed 849

I'm using clang-format from LLVM 7.0.0 with Windows 10 in C++.

I have following class

class FooooooooooooooooooC
{
public:
   FooooooooooooooooooC() = default;
   const FooooooooooooooooooC& operator=( const FooooooooooooooooooC& ) = delete;

};

and after running clang-format it should look like this

class FooooooooooooooooooC
{
public:
   FooooooooooooooooooC() = default;
   const FooooooooooooooooooC& operator=(
      const FooooooooooooooooooC& ) = delete;

};

But actually it look like this after running clang-format

class FooooooooooooooooooC
{
public:
   FooooooooooooooooooC() = default;
   const FooooooooooooooooooC& 
   operator=( const FooooooooooooooooooC& ) = delete;

};

My clang-fromat settings in .clang-format are

---
AccessModifierOffset: -3
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:   
  AfterClass:            true
  AfterControlStatement: true
  AfterEnum:             true
  AfterFunction:         true
  AfterNamespace:        true
  AfterObjCDeclaration:  true
  AfterStruct:           true
  AfterUnion:            true
  AfterExternBlock:      true
  BeforeCatch:           true
  BeforeElse:            true
  IndentBraces:          true
  SplitEmptyFunction:    true
  SplitEmptyRecord:      true
  SplitEmptyNamespace:   true
BreakAfterJavaFieldAnnotations: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
CommentPragmas:  '^ IWYU pragma:'
ColumnLimit: 80
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 3
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories: 
  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
    Priority:        2
  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
    Priority:        3
  - Regex:           '.*'
    Priority:        1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 3
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 1000000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpacesInParentheses: true
SpacesInSquareBrackets: true
Standard: Cpp11
TabWidth: 3
UseTab: Never
...

Does somebody know how to configure clang-fromat to create a break after

operator=(

Thanks!

1 Answers

In summary, you can't quite do what you want.

Here is how to configure clang-format to not put a break after const FooooooooooooooooooC&.

When deciding how to break up the line, clang-format uses several weighting factors whose names all start with Penalty. In this case, you desire the return type to stay on the same line as the function name, so you want to adjust PenaltyReturnTypeOnItsOwnLine. The value in your .clang-format is 60. Instead, use:

PenaltyReturnTypeOnItsOwnLine: 200

Make it any value 110 or larger to prevent the line from get broken after the const FooooooooooooooooooC& return type. I suggest 200 to match the pre-defined clang-format styles for Chromium, Google, and Mozilla. (Also, I don't know why 110 is the threshold; the penalty values are fairly opaque and I only found that value by experimenting.)

However, what you then end up with is this:

   const FooooooooooooooooooC& operator=( const FooooooooooooooooooC& ) =
      delete;

I don't believe there is any way to force the break after operator=(. If your class name was 4 characters longer, then you would get what you're asking for, because the above split before the delete would exceed 80 characters.


  • The comments above mention ColumnLimit. Even if you were allowed to increase the column limit, it would only allow you to keep the operator= declaration on one line. It wouldn't allow you to force it to split the line after operator=(.

  • The comments above mention AllowAllParametersOfDeclarationOnNextLine: false. As you discovered, this doesn't solve the problem. When there is more than one parameter, this affects the decision of whether all parameters get put onto separate lines. But you have only one parameter. (See the documentation.)


Finally, a caveat, I am using clang-format 6.0.0, compared to your 7.0.0. But there do not appear to be any differences in clang-format which would make any difference here:

  • The ReleaseNotes.html doesn't mention anything that would matter
  • There are several new clang-format style options in 7.0.0 compared to 6.0.0 (which I notice because clang-format 6.0.0 complains about them in your .clang-format file), but none are related to this issue.
Related