Skip to content

C++ Guidelines

Monday, 20 November 2023 | Adriaan de Groot


C++ is definitely a language that has Lots of Ways to do It – kind of like Perl’s TIMTOWTSAC. A consequence is that when writing code, you need to think about which way to do things. When context-switching between projects, employers, or what-have-you, you may have to context-switch preferences for which way is preferred. Guidelines can help, and I love them.

Automated Guidelines

I do love clang-format and clang-tidy (and before that, astyle), because they help apply automated guidelines that make a choice as to which way to do things like

  • place braces {}
  • leave spaces in template arguments <>
  • order includes
  • write names of types
  • avoid bug-prone constructs

Way back in the days of the English Breakfast Network (like, 2009) we wrote some tools to flag bug-prone constructs in KDE code, and encouraged people to clean those up. Nowadays other tools do a much better job.

I’m a big fan of auto-format-on-save within an IDE. That way I can type, copy-paste, futz around and have things cleaned up automatically. At $WORK, I use vscode and it does a good job of running tools in a remote container for formatting – as long as the file isn’t some 50000-line monstrosity, that is. I don’t know if KDevelop can do it, but my muscle memory on a Free Software platform switches to Konsole regularly to run formatting scripts, so I have never really investigated KDevelop’s capabilities there.

Toot me at kdedude on fosstodon.org if you know about KDevelop.

For Calamares I’ve been following the coding style laid down for that project for seven years. I still don’t like it, but it is automated (ci/calamaresstyle does the job) and reasonably well-described, so it is an automated guideline.

For $WORK, we have a fairly short .clang-format file – short because it doesn’t do anything weird, it’s basically “this other style, but put braces on lines on their own and move * to the other side”. Again, automated guidelines.

I think the most important part of this kind of automated guidelines is that reading code doesn’t take additional effort: the style is fixed, so there are zero surprises when reading code from Jane, Jim, or Joan.

Non-Automated Guidelines

Outside of what tools can apply automatically, there are still a lot of guidelines – rules-of-thumb, things-to-keep-in-mind – that can apply to any codebase. Not a week goes by that I don’t cite Kate Gregory’s Naming is Hard, but even when writing down the name of a Turdus migratorius, maybe there are variations to consider.

  • cock_robin
  • cockRobin
  • CockRobin

There are other cursed naming schemes possible, for sure. Let’s not go there.

When to use struct and when to use class in C++? That’s another thing you could argue about (in the language, the only differences is the default access specifier, but using one or the other can convey meaning to other developers).

For Free Software examples, consider Qt and KDE, which use a distinctive letter as the start of most class names (probably due to the lack of namespace support in the pre-standardization C++ era), which use camelCase for function names, etc .. If you spot setText you know it’s a function, and QLabel is a class, obviously. There’s no Label accessor, no get_text function either, and this consistency makes reading code easier.

At $WORK there’s a team of developers, and we task-switch a bit. One of the things we actively do is discuss coding style, so that reading other people’s code is as unsurprising as possible. We try to pack some extra meaning into names if we can.

The consequence of having these non-automated guidelines is that we regularly pick them up to discuss readability (e.g. when doing a review of new code) and we discuss and adapt the guidelines with some regularity – usually when some new and unexpected construct shows up. Recently we ended up with a long discussion about unmoveable objects and piecewise-construction, for instance.

The guidelines we use are now published by colleague Jan Wilmans, in a guidelines repository. I might not like all of the guidelines, but they save me thinking about which way to do things all the time, and that simplifies my life and improves the effectiveness of communication with my colleagues.

Takeaway

Write guidelines. Automate what you can. Document what you can’t. Make communication through code consistent, unsurprising, and readable. Collaborate. Follow existing style when possible.

The guidelines that Calamares uses, or my $WORK, might not be for you – write down your own. Fight for improvements. Write the simplest, most elegant, most readable and understandable code you can.