DEV Community

Graham Long
Graham Long

Posted on • Updated on

C coding quality tips

Introduction

In this post I shall be outlining some of the things that I personally apply to my C coding and the reasons why I apply them.
One caveat to this, which I feel is very important, when working in an established code base your code should follow the style of that code, consistency leads to easier to understand code than a mish-mash of styles.
So jumping straight in with....

Types

One thing which I do on every greenfield project is create a header file which defines custom types equivalent to the built in types but with the size as part of their name e.g.

Example typedefs

I do this because not all processors use the same size for all built in types, if the code needs to be ported to a processor with different sized types, then it is only this header file that needs updating and all other modules should work as before.
This also makes it clearer what value range a variable has when you declare it which can make it easier to catch bugs related to integer values overflowing during a code review.

Prefixing

One thing which I’ve not done before is prefix these custom types with a lowercase t, I have seen this, or similar annotations done and think it is a nice touch which I’ll probably adopt going forward.

Enums

I am a huge fan of Enums, any time when a variable has a finite number of values then I would use an Enum, it allows you to restrict the range of values passed as a function parameter and the values returned from a function.
It also in my opinion makes code easier to read as values can be named to something meaningful e.g. rather than 0 for OK and any other value for an error, status codes returned from a function can be:

Status codes example

Prefixing

Again this is something that I haven’t done but think would be a good addition is to prefix enums with a lowercase e to indicate that the value is an enum.

Enum values

As a general rule when using an enum I do not care what value each enumeration is, but when the value of an enumeration is used, it should always be defined, even if the values are 0, 1, 2 etc, most compilers set the values from 0 but this can’t necessarily be guaranteed, therefore I like to declare the values of enums when the value will be used in the software.
e.g. If the status codes above were checked against the value 0 in the code then I would instead define the value of each enumeration like this:

Status codes with values defined

Loops

These are minor things which I do regarding loops.
First, when incrementing a for loop index I use pre increment rather than post increment as this I have heard is minimally faster on most processors, the one exception I applied to this was when I worked with an msp430 processor, the compiler recommended I decremented the index as zero was easier to detect than non zero.

Secondly, when creating a super loop, instead of using while(1) I will use while(true), where true is non zero or for(;;), the reason for this is something i read which said while(1) could be confused with while(l), even as unlikely as this is I still prefer while(true).

Const

Whenever the value of a variable won’t change after it has been declared, I use the Const keyword to enforce its constant value, this has another positive in that it gives the compiler information that it can use to improve its optimisation of the code.

Another area where I use Const is with pointers as function parameters, it’s a great way of adding limits on changes to the data and address pointed to.
I can never remember the syntax for this so I always return to this post from geeksforgeeks.org.

Wrapping up

These points in this article are some of the things which I have picked up over my career, I’d love to hear your thoughts on these, and any other things that you apply when writing your C code.

Stay safe.
Graham

Top comments (2)

Collapse
 
ac000 profile image
Andrew Clayton

For your types you could typedef the POSIX fixed width types then you wouldn't need to change them, or you could just use them directly.

However they kind of look naff, so better to use nice short names like here, you'll find these are kind of standard, they are used throughout the Linux Kernel..

Collapse
 
longevitysoftware profile image
Graham Long • Edited

Good point for POSIX systems, I love the short type names as well.