DEV Community

Alexey Voinov
Alexey Voinov

Posted on

Does anybody know a good working C++ formatting tool?

I've tried clang-format. It doesn't do what I need, it is not very flexible and authors are refusing to create additional formatting options. But the main problem for me is that it cannot do incremental formatting. I cannot say: do just indentation and leave everything else as it is. It force to do my pet project in some corporate style, preventing even possibility of experiments with style.

I've tried astyle. It doesn't support complicated things like clang-format do, but it does a lot of options, and most of all, it does support incremental formatting. The problem is it fails to produce correct results on longer files. Looks like some buffer processing problem, because about every 300th line got weird. Sometimes even with syntax errors.

I've tried uncrustify. So far it is the best choice, but it still has some drawbacks. The configuration is really cryptic and I can't say that it is documented enough. I was able to configure it to do indentation only. And... it looks like it cannot properly indent nested classes.

Yes, I know, all of them are open source projects and can fix them or change them as I like. But first, that's not what I want to do right now, and second, I don't want to end up supporting my own private branch and spend time incorporating my changes on every version update or stick to some old and obsolete modified version.

Any other options?

Top comments (7)

Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Well, you just listed the two I'd suggest.

clang-format isn't going to force you to use a corporate style. You can select one as the default for anything unspecified, but if you're like me and want everything your way, you can go through and define everything.

I'm guessing that LLVM's unwillingness to create additional -style= designations is what you're referring to, but think about it - that's perfectly reasonable. Imagine if 200 people requested that their Pet Style were adopted! It would make a hash of the whole thing.

If you want to set your own style to reuse over and over, you create a .clang-format file for your project and reuse it. That's just how you're supposed to use it.

(Full docs are here.)

You can get a valid default clang-format configuration file via...

clang-format -style=llvm -dump-config > .clang-format
Enter fullscreen mode Exit fullscreen mode

And then change everything to what you want. Stick the .clang-format file in your project directory and use it for running clang-format. Easy breezy cider squeezy.

On that note, it really isn't a practical to leave anything in coding style to "do-whatever-I-don't-care". Experiment, settle on a style, and stick with it.

Collapse
 
voins profile image
Alexey Voinov

Thanks for your reply. Unfortunately, clang-format still cannot do what I want. For example, there's no option for colon to stick to what is there before it. At least, I wasn't able to find it. :)

For now I'm sticking with uncrustify for now. Except for couple of bugs it works quite well.

Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Are you referring to the colon of the initialization list specifically? Because, yes, that's in there. I can find it for ya when I get back to the office later, if you like. There's also one related to the ternary conditions.

Thread Thread
 
voins profile image
Alexey Voinov

The one in the class definition. And even then, clang-format doesn't do incremental formatting. :)

And yes, it would be nice to the option name if it is not big trouble for you. Just in case I'll use clang-format sometime later. :) I was able to find only option controlling the break before colon in the initialisation list.

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

Hm, okay. I know there's BreakBeforeInheritanceComma, but that appears to put the colon on the next line. I don't see something for the opposite, so it may indeed not do what you need there. :-\

Thread Thread
 
voins profile image
Alexey Voinov

Precisely. :) But thanks for trying.

Collapse
 
jmccabe profile image
John McCabe

Wow - this is old, but...

We've started using clang-format (14) at work, and I'm finding it very inflexible for our preferred code style. The idea really was to try to enforce a few simple rules, e.g. indentation and spacing, to start with, to avoid wasting time with trivia on pull request reviews, and we've got it configured to prevent commits that where the layout is 'wrong'. However, it's been really difficult trying to find a happy medium for some things because, as Alexey said, there are hardly any "ignore" options, and a lot of options that seem to cause funny things to happen such that we're ending up putting more and more // clang-format off / on comments around stuff we want to keep that way. That's got the unfortunate consequence that, if the bit we want to ignore is just the indentation, all the other formatting of the code within the off/on pair is also ignored, which isn't really what we'd like. The option to switch off specific rules around code would be useful; this appears to address it, but isn't there.

In relation to Alexey's comment about the authors refusing to add extra formatting options, the thread of comments on that clang-format issue is an example of this; there are a number of comments on there pushing back against the suggestion and claiming that clang-format adopters just need to accept that's how it is. In our case, we have a policy that the & (C++ reference) should be attached to the type name whereas the * (pointer) should be attached to the variable name, e.g. in:

Object *ptrToObject;
Object& refToObject;
Enter fullscreen mode Exit fullscreen mode

that's mostly to try to stop the &reftoObject looking like an instance of the address-of operator. This was, eventually, added to clang-format 14, but this comment, in relation to its implementation, is quite clearly an arrogant rejection of anything that doesn't fit with the authors' views.

It seems very much like a case of "we're writing this to make sure our own (clang) code is consistently formatted, and we've made it so you could possibly use it and tweak it for your needs but, if your needs don't fit with what our views, then you're on your own".

As a result, I'm taking a closer look at uncrustify now; it's far more configurable, and has many "ignore"able options, so could be more appropriate for our needs. Just need some time to set it up!