[clang-format] Indentation of preprocessor directives

Hi all,

I’ve written a working draft for a new clang-format option “PPDirectiveIndentation” (available at https://github.com/mkurdej/clang/tree/indent-pp-directives).
Basically, it indents preprocessor directives. So, the code

#if 0
#define A
#endif

becomes

#if 0

define A

#endif

when PPDirectiveIndentation = All.

So far, there are only two options (None, All), but I foresee another option Inner or something like that to mimic the behaviour of NamespaceIndentation.
The number of spaces between ‘#’ and the directive name is controlled by IndentWidth option (to be consistent with indentation inside namespaces, classes, blocks etc.), but it may be easily modified.

What’s the interest in it? Among well known source code that indents preprocessor directives, there are many Boost libraries (a quick search shows e.g. https://github.com/boostorg/asio/blob/develop/include/boost/asio/buffer.hpp).
What are the chances that it gets merged?

I’ll submit the code for revision to Phabricator this week when I find some more time.

Best regards,
Marek

Two common styles I come across are whitespace indentation after the ‘#’ but before the pre-processing directive:

#if 0

define A

#endif

and whitespace indentation preceding the ‘#’ prefixed pre-processing directive:

#if 0

#define A

#endif

Can this rule handle both styles, or do you plan on supporting both styles? I’m not specifically in support of one style versus the other, but I strongly support the idea of a tool that can normalise styles to some given convention, and the more flexibility the better. And of course no indentation at all:

#if 0

#define A

#endif

which you already handle.

Thanks,

MartinO

Is doing this even valid? I was under the impression that the C preprocessor required the hash to be on column 0. I’ve certainly had compilers reject code in the past where the preprocessor directives were indented accidentally.

David

Hi Martin and David, thanks for the interest.

I’ve had the same impression as David. But certainly, several modern compilers accept indented directives (clang, gcc, mscvc, icc).

Martin, may you be so kind and give some links to projects that use the space-before-hash style, please?

Anyway, it is pretty straightforward to add both styles. Do you have any ideas on naming? Should it be a single option (None, AllAfterHash, AllBeforeHash) or 2 options: one defining when to indent and the other - how to indent?

Regards,
Marek

śr., 31 sie 2016, 08:16 użytkownik David Chisnall <david.chisnall@cl.cam.ac.uk> napisał:

A good point, I’m not 100% sure if it is legal to precede the first ‘#’ with whitespace, though it seems to be commonly accepted. I’ll have to dig out my ANSI and ISO C documents.

I am not familiar with any Opensource project that uses this style, but I have seen it used in various companies I have done work for in the past; indeed, in one case it was part of their official coding practices. Interesting if it is not valid ISO C :wink: I’ve even seen examples such as:

/* comment */ #define foo …

Thanks,

MartinO

Can you attach this to https://llvm.org/bugs/show_bug.cgi?id=17362 ?

The # token may be preceded by whitespace; C standard (C99 and C11) 6.10p2 and C++11 chapter 16 p1.

The point of that style is so you can grep for ‘#include’ or ‘#define’ or whatever and be confident you won’t miss any.

–paulr