Skip to content

Instantly share code, notes, and snippets.

@diegoferigo
Last active June 20, 2017 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegoferigo/716259a64adb1035e383db3864805ac5 to your computer and use it in GitHub Desktop.
Save diegoferigo/716259a64adb1035e383db3864805ac5 to your computer and use it in GitHub Desktop.

I'm setting up these files for discussing a common clang-format that will be used across our projects. As far as I understood, using WebKit as base finds many of us happy. The first release has been generated by

clang-format --style=webkit -dump-config

A good starting point for the available options is Clang-Format Style Options.

Here below you can find some code that covers many cases, I'll keep this updated with the style agreed so far. I didn't find any demo code that already covers most of the C++ standard (any suggestion?). When discussing something, if it is not clear from the code below, please provide a code snippet to show your point. I'll include your example afterwards.

Demo Code

#include "include/header1.h"
#include "include/header2.h"
#include <iostream>
#include <vector>

namespace mynamespace {

class MyClass {
private:
    int m_int;
    vector m_vector;

public:
    MyClass()
        : m_int(42)
        , m_vector(10)
    {
    }

    ~MyClass() {}

    int getVar() const { return m_int; }

    void MyFunction(int j)
    {
        if (j < 10) {
            std::cerr << "Hello" << std::endl;
        } else {
            std::cerr << "World" << std::endl;
        }

        int list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        do {
            std::random_shuffle(list, list + 9);
            if (list[0] == 1)
                break;
        } while (is_sorted(list));
    }

    void f()
    {
        f(aaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
    }

    very::nested::namespaced::type function_long_line(very::nested::type1 t1, very::nested::type2 t2, very::nested::type3 t3) { return true; };
}

template <typename T, int size>
bool templated_function(T (&array)[size])
{
    return std::adjacent_find(array, array + size, std::greater<T>()) == array + size;
}

Discussion: HowTo

The discussion can happen in the comments, let's use +1 and -1 and optionally write a new comment for concerns. When discussing a single option, please provide the same code formatted with the .clang-format of this gist and the proposed one, pointing out the differences in the yaml file (provide a diff -u if you like things well done).

If after 2 weeks no concerns are raised, I merge the change and update the demo code. Especially in the beginning of this process, when an option receives good feedback and it looks reasonable from all of us, I merge it right after.

For many options, you can use this online tool for a live demo.

Eventually there is the problem of how to enforce the application of a specific style (PR-based? Does it exist a codacy bot for style?). Though this is still premature, let's find a clang-format with a wide agreement, and then decide on how to proceed.

Raw template for comments:

### Status: Open / Merged / Closed
### Description
Put here a brief description

#### From
```cpp
```

#### To
```cpp
```

#### .clang-format changes
```diff
--- clang-format
+++ clang-format-proposed
```
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: WebKit
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...
@diegoferigo
Copy link
Author

diegoferigo commented Jun 15, 2017

I start with an example.

Status: Open

Limit line length

Let's avoid to have very long lines, the horizontal scrolling when reading the code is annoying as hell. In my personal setup I use 100 columns, and I think it is a good compromise between too short lines (that could create mess with clang-format) and horizontal scroll.

From

very::nested::namespaced::type function_long_line(very::nested::type1 t1, very::nested::type2 t2, very::nested::type3 t3) { return true; }

To

very::nested::namespaced::type function_long_line(
    very::nested::type1 t1, very::nested::type2 t2, very::nested::type3 t3)
{
    return true;
}

.clang-format changes

--- clang-format
+++ clang-format-proposed

-ColumnLimit:     0
+ColumnLimit:   100

@diegoferigo
Copy link
Author

diegoferigo commented Jun 15, 2017

Status: Open

Arguments and parameters one per line

If the arguments / parameters don't fit one line, put them one per line.

From

    void f()
    {
        f(aaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa,
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
    }

To

    void f()
    {
        f(aaaaaaaaaaaaaaaaaaaaaaaaa,
          aaaaaaaaaaaaaaaaaaaa,
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
    }

.clang-format changes

--- clang-format
+++ clang-format-proposed

-BinPackArguments: true
-BinPackParameters: true
+BinPackArguments: false
+BinPackParameters: false

@traversaro
Copy link

traversaro commented Jun 16, 2017

I feel a bit stupid, but I did not really understood how to "use +1 and -1" for the various proposals.

@drdanz
Copy link

drdanz commented Jun 19, 2017

+1 on @traversaro's comment! 😆

@diegoferigo
Copy link
Author

diegoferigo commented Jun 20, 2017

@traversaro, sorry I missed your comment. Do you have any smarted idea on how to decide if you like / dislike a clang-format option? My proposal was to use thumbs up (+1) and down (-1) on the comment.

@traversaro
Copy link

What do you mean "use thumbs up (+1) and down (-1) on the comment". Here on Gist I can only comment the file, not the single comment, and apparently there are no "Reactions" like in usual GitHub .

@lucaTagliapietra
Copy link

@traversaro, I was thinking exactly the same. A possible solution could be manually citing the title of the comment we are referring to.

@diegoferigo
Copy link
Author

diegoferigo commented Jun 20, 2017

@traversaro Oww you're right! My bad, now I understand your concern. I stupidly supposed that without checking. I guess that here on gist the only option is what @lucaTagliapietra suggested, but it can become messy to follow many options. Any other suggestion?

@drdanz
Copy link

drdanz commented Jun 20, 2017

I suggest to use a normal issue for voting, it's going to be easier than manually counting +1s and -1s

@lucaTagliapietra
Copy link

+1 for @drdanz 😆

@diegoferigo
Copy link
Author

@drdanz I had in mind to avoid creating a standalone repo only for the clang format, but at this point this is the best solution. I'll move this gist in https://github.com/robotology-playground/clang-format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment