In order to reuse and port embedded software it is absolutely imperative that the code be written without any ambiguity. In a previous post, “Understanding Portable Types” located here, the basics of portable types were discussed and how the common types of char, int and long may mean different things depending on the architecture and compiler that is used to compile the code. The use of the ISO C99 fixed width integers were just the first step. The next step is to understand these five tips for using portable types.
Tip #1 – Use the standard C library types
There are two different libraries defined in C99 that are very useful for defining portable types. The first header file is stdint, which defines fixed width integers such as uint8_t, uint16_t and uint32_t. Fixed width integers are often custom defined by developers in their own typdefs header file. Custom definition is completely unnecessary and should in fact be avoided! Use standard libraries wherever possible and applicable (within reason). The second library that should be kept in mind that has a similar problem of custom definition is Bool. Developers often create their own custom type when it is no longer necessary. If a compiler doesn’t support C99 or better then its time to go compiler shopping!
Tip #2 – Don’t custom define true and false
Custom definitions of true and false are extremely common in embedded software. This is very unfortunate because it often causes the issue of having multiple versions defined within a single project. For example, it isn’t uncommon to see TRUE, True, true and FALSE, False, false all defined within the same project! Use a library such as stdbool to prevent this type of issue from cropping up.
Tip #3 – Shy away from custom integer types
A great reason for using a standard library for portable types is that the project ends up with well, standard types. The temptation to define custom integer types such as vuint16_t and vsint16_t are greatly curbed. Defining extra types such a volatile uint16_t may seem like a good idea but when reviewing code it is too easy to miss the v! A developer is far better off seeing the word volatile than inferring it through a short hand notation.
Tip #4 – Use enumerated custom types
There are times when a developer will want to custom create a type. One of the best ways to do this is through the use of an enumeration of structure. The use of a custom type is perfect in order to ensure that certain definitions are appropriately matched or when a declaration might otherwise be very complex. For example, creating an enumerated type to define possible mask values that are used to initialize a register is the perfect place to use such custom definitions.
Tip #5 – Custom types should have _t
Portable types defined in the C99 standard use _t at the end of the type to show a developer that the keyword is a type specifier. When developing a custom type, engineers should adhere to the same standard for signifying a type and add _t to the definition. In the past I have seen and used the full word Type but in keeping to ANSI-C and limiting a single line to 80 using the shorter _t provides the same amount of clarity with a 2 character savings.
Using and creating portable types is relatively easy and straightforward provided that care is taken. Developers should use the standard library types rather than creating their own custom version of the same types. If a type doesn’t exist within a library then it may make sense to create a custom type provided it is for an enumerated or structure type.