When the term “coding standard” or “coding guideline” is brought up in a team meeting or training session, I will sometimes feel a sudden ten-degree drop in temperature in the room, the lighting dims to an eerie glimmer, and ominous dark clouds form spontaneously over the heads of developers and team leads alike. Rather than shy away in fear and loathing from this topic, I face it head-on by sharing my philosophy about coding standards
The purpose of a coding standard is to improve the readability, maintainability, reusability, portability, and reliability of your code. These are all good, desirable code attributes, true?
Whether in a workplace or in an open-source project, teams will often adopt a coding standard, which all team members use consistently. When you are developing programming skills, adhering to a coding standard helps you develop consistent, disciplined coding habits, which will become second-nature to you over time. If you’re an experienced developer, adhering to a coding standard ensures that your code fits into the existing project to create a cohesive whole. And using a coding standard will also help you adapt to other coding standards in other courses or in the workplace.
When you develop source code, you’re not just communicating with the compiler; you are communicating with everyone who will ever read your code. That might include:
- The future you a week, a month, a year, or a decade after you originally wrote the code.
- Your colleagues, your team lead, and your manager.
- In an open-source project, anyone in the world, including potential employers.
- In a programming course, your instructor, and sometimes your classmates.
Getting your code to pass the compiler without complaint is just a bare minimum step. You are writing your source code for human readers as well.
You might not agree with all of rules and guidelines in the coding standard. In most environments, you are always welcome to question or discuss the reasoning behind or justification for specific rules and guidelines, but you are still responsible for abiding by them in your programming projects.
Everyone has a different set of experiences, and those experiences shape our differing opinions. That said, based on my own experience as a software engineer, mentor, team leader, manager, director, and programming instructor, I strongly disagree with the statement “Coding rules and comments are best done after the code has been made to work.” Unless the project is trivially small and is only being worked on by one person in one sitting, leaving readability and comments until after the software is completely working is a recipe for delays and frustration.
If more than one person is working on the code, or if one person needs to leave the code and come back to it after a few hours or days, the code and comments must clearly show what’s happening – as the code is being developed. Otherwise, too much time is wasted trying to figure out what’s happening. I’ve met some rare and brilliant folks who can keep a lot of details in their head for long periods of time. But even these people have their limits, and I’ve seen them run into the wall of having to slowly decipher their own (or a teammate’s) poorly-formatted, poorly-documented code. It just slows everything down.
Leaving “cleanup” to the end is a risk to any project. Based on my project experience, the only way to end up with readable, properly commented code is to make it that way while the code is being developed. Otherwise, realistically, the cleanup either never happens or isn’t done very well, and then the code becomes vulnerable to being completely thrown away and rewritten, early in the maintenance phase of the software development life cycle. So, writing code that isn’t readable and maintainable is incredibly wasteful.
Having experience with several very large C projects (on very large teams) with coding standards enforced by software tools, many medium-sized projects without any coding standards, and everything in between, and given that the maintenance phase typically accounts for roughly 80% of the cost of a non-trivial software product’s life cycle, I have reached the following conclusions:
- Consistency – When considering adopting a reasonable coding style (e.g., brace placement, whitespace, indentation policy, etc.), consistency within a project is more important than what style specifics are actually adopted. We all have strong preferences, and most can justify them with a combination of real and fabricated statistics to support our positions. But being inconsistent across a project can slow things down considerably, during both development and maintenance. I’ve seen it happen many times, and have seen the adoption of a consistent style within a project lower the team’s frustration level and increase team productivity, even among those who don’t agree with the specific details of the adopted style.
- Readability – Any rule that improves readability for the maintainer (another person and/or the future you) is worth having. Unfortunately, code readability remains more subjective than it should be. There are many studies of and formulas for prose text readability, but precious little on code readability. My rule of thumb has become…if something is hard to understand immediately, make the effort to make it easier to understand. Readability rules and guidelines should support this idea.
- Reliability – If there’s a common programming error or class of errors that the compiler can’t catch, the runtime behavior would not be immediately obvious during initial testing, and a simple rule in the source code could avoid it completely, then the rule is worth having. My view on this has evolved, as compilers and other tools have become significantly smarter about catching these sorts of things, at least by generating warning messages.
- Cleanliness – Clutter should be avoided like the plague. Avoid comments that just restate the obvious (e.g., “increment the pointer,” or “here are the local variables,” etc.), comments added only to increase the comment-to-code ratio, unused variables, unreachable code, etc. This chaff just distracts and slows down the reader and increases frustration levels.
- Great Names – Reasonable naming conventions are important, to make it clear what the entity does or what it contains. While I am a fan of placing a ‘p’ in front of pointer variables (e.g., in C and C++), I am not a fan of encoding the entire data type into the variable name (e.g., Hungarian notation) – which often just leads to less-readable code and extra maintenance work, should the data type ever need to change.
- No Rules Just for Rules Sake – Rules that do not serve to directly improve readability, maintainability, reliability, reusability, or portability, should be eyed with strong suspicion.
When I present it this way to a team, the temperature in the room returns to normal (aka, room temperature), the lights return to their former brightness, and at least most of the clouds over developers’ heads dissipate. Of course, there’s at least one remaining cloud in every crowd.
Note – If you want to see C source code that is actually designed to be obscure, and is the complete antithesis of readable, maintainable code, visit the International Obfuscated C Code Contest. But, please do not look to this site for examples of good coding practices. These are clever examples, but are also examples of how not to code in production projects.