Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang-format: Setting to control C++ attributes

Tags:

clang-format

Searching through the Clang-Format Style Options, I can't seem to find a way to control the behavior on the placement of C++ attributes.

As an example, take these two declarations, the first of which does not overflow the column limit and the second of which does:

template <typename TChar> [[gnu::always_inline]] static ptr<TChar> within_limit(ptr<TChar> first, ptr<TChar> last);  template <typename TChar, typename FApply, typename... FApplyRest> [[gnu::always_inline]] static ptr<TChar> overflow(ptr<TChar> first, ptr<TChar> last, const FApply& apply, const FApplyRest&... apply_rest); 

No matter how I tweak my .clang-format, the output is some variant of this:

[[gnu::always_inline]] static ptr<TChar> within_limit(ptr<TChar> first, ptr<TChar> last);  [[gnu::always_inline]] static ptr<TChar> overflow(ptr<TChar> first, ptr<TChar> last, const FApply& apply, const FApplyRest&... apply_rest); 

Having the attributes on the same line as the type is rather unreadable (to me), so I would prefer clang-format not do this. Using __attribute__((always_inline)) exhibits the same behavior. Specifying multiple attributes in a single list ([[noreturn, gnu::cold]]) causes reformatting (to [[ noreturn, gnu::cold ]] for reasons unclear to me). The formatter has at least some basic understanding of attributes.

SO: Is there a way to get clang-format to put attributes on their own line (the C++ equivalent to BreakAfterJavaFieldAnnotations)?


Attempted Workarounds

Use of // clang-format off/// clang-format on is an okay stopgap, but it is definitely too ham-handed for a permanent solution. I still want the declaration formatted properly. Aside from that, the project requires the use of a lot of attributes, so having clang-format comments everywhere is arguably less readable.

Use of CommentPragmas theoretically would allow me to be more localized in disabling, but the output is still quite odd:

template <typename TChar> [[gnu::always_inline]] // NO-FORMAT: Attribute     static ptr<TChar>     within_limit(ptr<TChar> first, ptr<TChar> last); 
like image 809
Travis Gockel Avatar asked Aug 17 '17 16:08

Travis Gockel


People also ask

Does clang-format work for C?

clang-format is located in clang/tools/clang-format and can be used to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code.

Does clang-tidy work for C?

Clang-tidy uses the same front-end libraries as the Clang C language compiler. However, because it only takes source files as input, you can use clang-tidy for any C or C++ codebase no matter what compiler you are using.

How do you customize your clang-format?

clang-format supports two ways to provide custom style options: directly specify style configuration in the -style= command line option or use -style=file and put style configuration in the . clang-format or _clang-format file in the project directory.

What is ClangFormat?

Clang-Format is a widely-used C++ code formatter. As it provides an option to define code style options in YAML-formatted files — named . clang-format or _clang-format — these files often become a part of your project where you keep all code style rules.


1 Answers

This is not a "solution", but a general workaround for preventing clang-format (and other formatters) from removing line breaks.

Just add an empty line comment at the end of a line like so:

template <typename TChar> [[gnu::always_inline]] // static ptr<TChar> within_limit(ptr<TChar> first, ptr<TChar> last);  template <typename TChar, typename FApply, typename... FApplyRest> [[gnu::always_inline]] // static ptr<TChar> overflow(ptr<TChar> first, ptr<TChar> last, const FApply& apply, const FApplyRest&... apply_rest); 

It can't merge the lines now, as this would comment out the entire rest of the line.

For this specific example, it's unfortunately not perfect, as it also seems to introduce a second line break after the return type (which looks arguably worse than having everything on a single line). Nontheless I thought this might come in handy in some scenarios (although I haven't personally used it all that much either).

It's at least a lot less verbose than turning off clang-format completely for just a single line.

like image 84
Possseidon Avatar answered Sep 21 '22 15:09

Possseidon