clang-format:设置控制C++属性

Tra*_*kel 22 clang-format

通过Clang-Format样式选项进行搜索,我似乎无法找到控制C++属性放置行为的方法.

举一个例子,取这两个声明,第一个不会溢出列限制,第二个声明:

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);
Run Code Online (Sandbox Code Playgroud)

无论我如何调整我.clang-format,输出都是这个的一些变体:

[[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);
Run Code Online (Sandbox Code Playgroud)

将属性与类型放在同一行是相当难以理解的(对我而言),所以我不希望clang-format这样做.使用__attribute__((always_inline))展品的行为相同.在单个列表中指定多个属性([[noreturn, gnu::cold]])会导致重新格式化([[ noreturn, gnu::cold ]]由于我不清楚的原因).格式化程序至少对属性有一些基本的了解.

SO:有没有办法让clang-format属性放在自己的行上(C++相当于BreakAfterJavaFieldAnnotations)?


尝试过的变通方法

使用// clang-format off/ // clang-format on是一个好的权宜之计,但绝对是一个永久解决方案.我仍然希望声明格式正确.除此之外,该项目需要使用许多属性,因此在clang-format任何地方都有评论可读性较差.

CommentPragmas理论上的使用将允许我在禁用中更加本地化,​​但输出仍然很奇怪:

template <typename TChar>
[[gnu::always_inline]] // NO-FORMAT: Attribute
    static ptr<TChar>
    within_limit(ptr<TChar> first, ptr<TChar> last);
Run Code Online (Sandbox Code Playgroud)

小智 4

您要求的功能已以 clang-format 16 添加。该属性称为BreakAfterAttributes (documentation),您要求的行为(属性组后的换行符)为Always

文档中此属性的部分:

属性后中断

在函数声明/定义名称之前的一组 C++11 属性之后中断。

可能的值:

  • ABS_Always(在配置中:)Always始终在属性之后中断。
[[nodiscard]]
inline int f();
[[gnu::const]] [[nodiscard]]
int g();
Run Code Online (Sandbox Code Playgroud)
  • ABS_Leave(在配置中:)Leave保留属性后面的换行符不变。
[[nodiscard]] inline int f();
[[gnu::const]] [[nodiscard]]
int g();
Run Code Online (Sandbox Code Playgroud)
  • ABS_Never(在配置中:)Never切勿在属性之后中断。
[[nodiscard]] inline int f();
[[gnu::const]] [[nodiscard]] int g();
Run Code Online (Sandbox Code Playgroud)

从 clang-format 17 开始,似乎没有在组中的每个属性之后进行中断的设置。如果有人对此感兴趣的话。例如:

// Even `Leave` will format this into one line
[[gnu::const]]
[[nodiscard]]
int g();
Run Code Online (Sandbox Code Playgroud)

Possseidon另一个答案中建议的行注释技巧将适用于此。

// Will remain like this when using `Leave` or `Always`
[[gnu::const]] // <-- Empty line comment after each attribute you want a break after
[[nodiscard]]
int g();
Run Code Online (Sandbox Code Playgroud)