13.1 C
New York
Sunday, December 4, 2022

Programming embedded systems: Standard integers and mixing integer types – Embedded


Integer arithmetic seems like an elementary school subject. But in programming, you should definitely not underestimate it. In fact, all safer C language subsets (e.g., MISRA-C:2012 [1]) have a whole category of rules for integer arithmetic. Interestingly, these tend to be the most frequently violated rules in almost any code base. So, what makes integer arithmetic so tricky? What are the C language rules? How to avoid some of the most common pitfalls? Please watch video lesson #11 to find out:
Lesson 11 – Standard integers <stdint.h> and mixing integer types

Integers in mathematics are simple because there is only one kind: the unlimited numbers that can go on forever from -∞ to +∞. But in programming, numbers have a limited range, such as 8-bit, 16-bit, 32-bit, or 64-bit. Each range requires special treatment. Moreover, numbers can have different signedness assigned to them (signed vs. unsigned). This means that the same bit patterns in the number representation can be interpreted differently depending on the range and signedness assigned to the number. For example, a bit pattern 0xFFF6 can be interpreted as a 65526 16-bit unsigned value, a -10 signed 16-bit value, or a 65526 signed 32-bit value. (Please refer to lesson #1 to refresh your memory about the two’s complement representation.) Now, consider the implications of mixing all these different integer types in expressions!
The first step in simplifying the integer problem is knowing the range and signedness assigned to a given number. Unfortunately, the “C-native” integer types, such as ‘int’ and ‘char’ as well as the ‘short,’ ‘long’ and ‘unsigned’ qualifiers, are intentionally ambiguous. For example, ‘int’ might have a 16-bit range on an 8-bit or 16-bit CPU, a 32-bit range on a 32-bit CPU, and a 64-bit range on a 64-bit CPU.
This ambiguity has been a big problem for decades, especially in embedded programming. But finally, the problem was addressed formally in the C99 [2], which introduced the standard integer types defined in the header file <stdint.h>. Some examples of integers from <stdint.h> include: uint8_t, int16_t, or uint32_t.
For embedded programmers, <stdint.h> is arguably the most valuable feature in C99 because of the standardized names and, more importantly, because now the compiler vendor is responsible for providing the portable integer types with a known range and signedness. But to take advantage of this, you need to use the <stdint.h> integers instead of plain ‘int,’ ‘short,’ or ‘char.’ Inventing your own homegrown integer type names is counterproductive. (See also MISRA-C:2012 Directive 4.6 [1].)
While <stdint.h> integers definitely help, to understand how an expression will be evaluated, you still need to know the integer promotion rules in C [2], which depend on the CPU. This is especially true when you mix different integer types in expressions. The lesson #11 video presents some of the most important rules and illustrates them with examples, so I do not repeat them here.
The plain integer constants in C represent signed integers. For example, the constant 0 means signed integer zero (strictly speaking, signed octal zero). But you can also make explicitly unsigned constants by providing suffixes “U” or “u.” For example, 0U represents an unsigned integer zero. Other examples are 1U, 5u, 0xDEADBEAFU. Applying the suffixes “U” (or “u”) for unsigned integer constants is an easy way of improving your integer expressions. (The suffixes “U” or “u” are also required by MISRA-C:2012 Rule 7.2 [1].)
Integer arithmetic is a fertile ground for bugs in C, and despite my decades of experience, I still make mistakes with integers. The subject is complex, and this lesson #11 barely scratches the surface. To learn more, I recommend reading the C99 Standard [2] and the MISRA-C guidelines [1], especially Section 8.10, “Essential type model.” Using a static analysis tool is also a highly effective technique to reduce bugs with integers. When you run static analysis, you should enable MISRA-C checking as well.
Finally, if you want to test your understanding of integer arithmetic, a timely quiz has just been published on EmbeddedRelated.com. So far, over 90% of participants get it wrong, which proves my point. Let’s see how you’ll fare…
[1] MISRA-C Standards
[2] ISO/IEC 9899:TC3 Standard (C99)
Related Contents:
For more Embedded, subscribe to Embedded’s weekly email newsletter.

You must or to post a comment.
This site uses Akismet to reduce spam. Learn how your comment data is processed.


Related Articles


Please enter your comment!
Please enter your name here

Latest Articles