C++ Guidelines
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.