Sunday, January 20, 2013

An argument against stdint.h

An argument against stdint.h:
I've only been programming C for about 15 years, so for the vast
majority of that time I've been using C99. And most of that time has
been spent writing low-level code (operating systems, drivers,
embedded systems). In these kind of systems you care a lot about the
exact sizes of types, since memory and cache are important as so is
mapping variables to memory mapped registers. For this reason having a
standard way of declaring variables of a certain bitsize struck me as
a pretty smart thing to do, so I've almost always used
stdint.h on my projects. And in the rare cases where it
wasn't available used some close equivalent. However, there is an
argument to be made against using them (an extension of the general
argument against typedefs). The core of the argument against is that
it hides information from the programmer that is vital in constructing
correct programs.

Let's start with some simple C code:

unsigned int a;
unsigned int b;

The question is, what is the type of the expression a + b.
In this case, things are fairly straight-forward. The results expression
has the type unsigned int.

Slightly trickier:

unsigned short a;
unsigned short b;

In this case due to integer promotion the operands are
promoted to int and therefore the resulting expression is
also of an type int. Integer promotion is a little
obscure, but relatively well known. Most of the time this isn't really
a problem because if you assigned the expression back to a variable of
type unsigned short the effect will be the same. Of
course if you assign it to an unsigned int, then you are going to be
in trouble!

So nothing really new there. There is some obscurity, but with local
knowledge (i.e: just looking at that bit of code), you can tell with
complete accuracy wha The problem occurs when you have
something like:

uint16_t a;
uint16_t b;

So, now what is the type of the expression a + b? The
simple answer is it depends. The only way to know the
answer to this question is if you know what the underlying type of
uint16_t is. And this is a problem, because the
correctness of your program depends on being able to answer that
question correctly. The unfortunate result of this is that in an
attempt to make code more portable across different platforms (i.e.:
by not relying on the exact sizes of types), you end up in a situation
where the correctness of your program still depends on the underlying
platform, although now in a nasty obscure manner. Win!

Of course, most of the time this doesn't matter,
but in the times where it does matter it is certainly a problem.
Unfortunately, I don't have a good suggestion on how to avoid this
problem, other than careful coding (and I really hate having to rely
on careful coding just to essentially get type safety correct).
If you've got a good suggestion please let me know in the comments.

Of course, I think I will still continue to use stdint.h
despite these problems, however it is certainly something that C
programmers should be aware of when using these types.

DIGITAL JUICE

No comments:

Post a Comment

Thank's!