According to Arne Mertz, using programming rules and guidelines helps developers work together, as they result in more consistent and better code. However, using them the wrong way can have the opposite result – code that is cumbersome to read or solves problems in suboptimal or even wrong ways.
Arne Mertz gave a talk about programming rules and guidelines at NDC Tech Town.
Mertz explained the differences between rules and guidelines:
A rule is more or less absolute. It has to be followed wherever it applies, breaking the rules is usually not acceptable.
A guideline is a best practice or sensible default – we may have reasons to diverge, and that’s OK.
Knowing this difference is important, because interpreting or stating a guideline as a rule leads to developers breaking the code rather than the guideline, Mertz argued:
It’s in the nature of guidelines that there are cases where they do not apply, and trying to stick to them regardless in such a case often leads to code that is cumbersome and less readable or even outright wrong.
For developers, strict rules seem more convenient, Mertz said. The compiler is very strict about what it accepts. We have so many complicated problems to solve that a set of rules to follow blindly takes a lot off our shoulders.
In his talk, Mertz explored several rules and guidelines. He explained where the rule “don’t use exceptions” comes from:
I’ve seen the “don’t use exceptions” rule (or guideline) come up in various contexts for almost two decades. When you track down the origins, it comes from the Google style guide, which says “We do not use exceptions”.
That tiny difference is extremely important, Mertz said, as it states that Google does not use exceptions. The style guide elaborates why; it’s not because exceptions are considered bad, but because at Google there is a lot of code in use that is not written with exceptions in mind. Introducing exceptions to such a code base would introduce the risk of introducing undefined behaviour and the need to rework large parts of their existing code base, as Mertz explained:
Google adopted this guideline out of necessity, and, from what I have been told by people who have worked at Google, it is not followed everywhere, Mertz said.
When encountering this guideline in projects, pointing out the origins and the fact that it is a guideline for old large projects can lead to the guideline being dropped, Mertz said; unless of course, by that time the project in question also has grown over years without exceptions in mind and introducing them would lead to the same problems that made Google adopt the guideline, he added.
Another rule that Mertz explored was “every function shall have a single return statement”. This rule is part of several sets of guidelines and rules, e.g. the MISRA C and MISRA C++ rules. The reasons for this rule vary, as Mertz explained:
Some cite readability in longer functions, but the counterargument is to make functions shorter in the first place. In languages like C, early returns might accidentally omit resource cleanup, which is bad.
This argument does not count when you use C++ with RAII classes where the compiler guarantees cleanup through destructors, Mertz mentioned.
InfoQ interviewed Arne Mertz about the impact that following programming rules and guidelines can have.
InfoQ: What’s your view on the guideline “don’t use exceptions”?
Arne Mertz: Exceptions are a core feature of the C++ language to report errors. Not using them regularly leads to the use of error return codes and out parameters which makes the code harder to read and reason about. There are modern library solutions like std::expected that alleviate these issues somewhat, but I have never seen them being used in projects where exceptions were shunned due to the Google guideline.
I gather that especially in the early 2000s, Google as a software company was a hip role model, so people wanted to emulate them. They adopted this guideline without questioning its necessity for it in a code base that is completely different.
InfoQ: What can be the impact of following the rule “every function shall have a single return statement”?
Mertz: Following the rule often results in some variant of the “retVal” variable that often is initialised with a nonsensical value that hopefully later gets assigned the real return value. In addition, we often see either a variable to track whether we’re on a good path or not, or a deeply nested control flow. All these patterns tend to make the code more convoluted and reduce readability.