Obviously, things done “today” can be quite different than how things were done 30 years ago, especially in regards to computers. Is it strange that out of all the places I’ve worked where I wrote code that only one of them had an actual “coding standard” we had to follow? (And that was at a giant mega-corporation.) All the others seemed to have folks who just carried on how things were, for the most part, or were given the freedom to code as they wanted as long as they followed some specific system (such as “Clean Code” at a startup I worked at).
My day job has been undertaking an official coding standard. I started by documenting how things were done in the millions of lines of code we maintain. Over my years here, I have introduced some things from the mega-corporation’s standards into our code base, such as prefixing static variables with “s_” or globals with “g_” or similar.
But why reinvent the wheel? I thought it would make a lot more sense to find an existing standard that applied to embedded C programming and just adopt it. That led me to this:
https://barrgroup.com/embedded-systems/books/embedded-c-coding-standard1
This document clearly states the “why” for any requirement it has, and I have learned a few things. Unlike most standards that are mostly cosmetic (how to name functions or variables, how wide is a tab, etc.), this one focuses on bug detection, bug reduction and making code easier to review.
Which brings me to snake case…
https://en.wikipedia.org/wiki/Snake_case
Most places I have worked use camelCase, where all words are ran together (no spaces) with the first letter in lowercase, then all subsequent words starting with uppercase. itWorksButCanBeHardToRead.
The mega-corp standard I worked under would refer to “camel case starting with an uppercase letter,” which I have since learned is known as PascalCase. ItCanHaveTheSameProblem when the eyes have to un-smush all the letters.
snake_case is using lowercase words separated by underlines. A variant, SCREAMING_SNAKE_CASE uses all uppercase. (I never knew the name of that one, but most places I worked use that for #defines and macros and such.)
…and I expect someone will comment with even more naming conventions than I have encountered.
Do. Or do not. There is no try.
Beyond “how stuff looks,” some suggestions actually matter. Something I only started doing in recent times is when you put the constant on the left side of a comparison like this:
if (42 == answer)
{
// Ultimate!
}
I saw this for the first time about a decade ago. All the code from a non-USA office we interacted with had conditions written “backwards” like that. I took an instant dislike to it since it did not read naturally. I mean who says “if 225 pounds or more is your weight, you can’t ride this scooter”?
However, all it takes is a good argument and I can flip on a dime. This flip was caused by finding multiple bugs in code where the programmer accidentally forgot one of the equals:
if (answer = 42)
{
// Ultimate?
}
If you use a modern compiler and have compiler warnings enabled, it should catch that unintended variable assignment. But, if you are using a “C-Like” embedded compiler that is missing a lot of modern features, it probably won’t. Or, if even you are running GCC with defaults:
https://onlinegdb.com/pv5Yz24t2
And thus, I broke my habit of making code that “reads more naturally” and started writing comparisons backwards since the compiler will fail if you do “42 = answer”.
This week, I learned they refer to this as Yoda conditions. Of course they do.
https://en.wikipedia.org/wiki/Yoda_conditions
Snakes. Why did it have to be snakes?
This week I read one sentence that may make me get away from camelCase and PascalCase and go retro with my naming convention. It simply had to do with readability.
is_adc_in_error is very easy to read. I’d say much easer than IsAdcInError which looks like some gibberish and requires you to focus on it. If anyone else is going to review the code, being able to “parse” it easier is a benefit.
I am almost convinced, even if I personally dislike it.
Give me some reasons to stick with camelCase or PascalCase, and let’s see if any of them are more than “’cause it looks purtier.” (For what its worth, I’ve seen camelCase for global functions, and CamelCase for static functions.)
Awaiting your responses…
