Re: C99 exact width integers usage - informal survey

On Sat, 01 Mar 2008 23:15:01 -0600, Jack Klein wrote:

On Sat, 01 Mar 2008 14:11:34 -0600, Tim Wescott <tim@xxxxxxxxxxxxxxxx>
wrote in comp.arch.embedded:

On Sat, 01 Mar 2008 08:54:18 -0800, Marco wrote:

How many developers here are using exact width integer types as
defined in C99?

If not why?

This could be by using <stdint.h> or by creating your own .h file.

example for typical 32 bit CPU:

/* Exact-width integer types. C99 Standard */ typedef signed char
typedef signed short int16_t;
typedef signed long int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;

Not very much, unless a customer asks. I know that I'm swimming
upstream, but here's my reasons:

* ANSI compliant compilers guarantee minimum sizes for char, int, and
long, so you can write perfectly portable code (assuming ANSI
compliance) if you observe the constraints.

Well, yes and no on the portability issue. Unless you never use the
types int and unsigned int. If you don't completely bar them from your
code, you just might mistakenly use int on a 32-bit processor and it
works just fine. Then you move the same code to a 16-bit processor and
it breaks when you try to put 100000 into it.

So you always need to use long and short, never int, if you want

A short int isn't a guaranteed 16 bits any more than a 'regular' int is.
It's only guaranteed to be no shorter than 16 bits, and no longer than
'int' for the same compiler.

And a long isn't guaranteed to be longer than an 'int' -- just no shorter
than 32 bits, and no shorter than an 'int' on the same compiler.

If you want portability, you have to make sure that your code won't break
when you exceed 0x7fff (not 100000) in an integer _or_ a short, and you
won't be guaranteed that your particular implementation will provide a
check unless you -- check.

* Many DSPs have a native word size longer than 8 bits, and there's a
few from Freescale that come in increments of 24 bits. So I can't
write portable code for my market using int8_t that's not misleading.

Yes, there are architectures widely used in embedded systems, mostly
DSPs, that have a byte size of 16, 24, or 32 bits.

That's why the exact sized int types are not required in C99 unless the
implementation has those exact width 2's complement types.

I can't think of code that is less portable than code that won't even

But the
"int_least#_t" and "int_fast#_t" types are required on all
implementations, for 8, 16, 32, and 64 bits.

These I could maybe see as being useful -- but they also violate your
condition on the use of 'int', that they may be bigger than expected.

As I said in my reply to the OP, I've written both ends of the parsing
and formatting code for CAN (and other binary) communications
interfaces, where code has to be pulled out of, or packed into, an
arbitrarily aligned octet stream. One end was a 32-bit ARM with 8-bit
bytes, the other end a TI 2812 DSP with 16-bit bytes. I used
int_least8_t on both sides, and the same code compiles, and runs, on
both sides.

Ultimately these 'exact width' integers foster a delusion of
exactitude, but they don't provide the real thing. Using char, short,
int and long gives me certainty of minimum size (assuming ANSI C), and
if I absolutely have to depend on a variable being some exact width
then I either mask it myself, use exact width specifiers (with tart
comments about non- portability to odd-word-length processors), or put
that particular section of code in a file that clearly indicates the
limits to portability.

I fail to see what you mean by "delusion of exactitude". On a Freescale
56K DSP with 24-bit bytes, none of (u)int#_t exist for 8, 16, 32, or 64

Until some bozo defines them to make some otherwise perfectly portable
code compile because some other character used int16 or int8 because they
thought it would be cool.

But the (u)int_least#_t and (u)int_fast#_t types do. The exact
width type definitions do not exist in stdint.h if the architecture does
not natively support the underlying types.

It is quite simple to build a usable stdint.h header, in some cases
excepting the 64-bit types, for any conforming C compiler all the way
back to the original 1989 ANSI standard.

I'm sorry. What I see here is even more reasons to avoid 'int_xx' types
like the plague. I can see some value in 'int_least_xx' and
'int_fast_xx', but not much that I can't get from 'char', 'short', 'int'
and 'long'.

Tim Wescott
Control systems and communications consulting

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott