tags:

views:

1593

answers:

6

Occasionally I need to use fixed-width integers for communication with external devices like PLCs. I also use them to define bitmasks and perform bit manipulation of image data. AFAIK the C99 standard defines fixed-width integers like int16_t. However the compiler I use, VC++ 2008 doesn't support C99 and AFAIK Microsoft is not planning to support it.

My question is what is the best practice for using fixed-width integers in C++?

I know that VC++ defines non-standard fixed-width integers like __int16, but I am hesitant to use a non-standard type. Will the next C++ standard define fixed-width integers?

+6  A: 

You can workaround the problem with some #ifdef directives.

#ifdef _MSC_VER
   typedef __int16 int16_t
#else
   #include <stdint.h>
#endif
Mehrdad Afshari
+1 Clever solution, nicely done!
Andrew Hare
+4  A: 

Include the file <stdint.h> to get the definitions for types like uint16_t. VC++ doesn't come with <stdint.h> by default, but you can get that file from several places. Wikipedia lists a few, and Google will find you lots more.

Adam Rosenfield
The problem is that stdint.h, like most or all C and C++ headers, is implementation-specific. The definitions depend on the implementation. Any random header might work just fine, or fail.
David Thornley
@David: That's a good point, but in this case the stdint.h files listed on the Wikipedia page are in fact specifically written for MSVC++.
j_random_hacker
Ah, so we aren't talking about random headers here. Good.
David Thornley
+1  A: 

Will the next C++ standard define fixed-width integers?

Yes.

As Mehrdad said, you can use #ifdefs for now. An alternative would be some elaborate template magic. Boost has got something in this direction, the Boost Integer library.

Konrad Rudolph
A: 

There are different paths to take. Most environments would hold that short ints are 16 bits, and long ints are 32. (The long is implied when you declare simply int.) If you typedef your own int16 type, you'll probably end up using a short int.

Another possibility lies with bit fields in structs. You can say something like:

struct x {
    int a : 16;
    int b : 5;
    ...
};

And so forth. If you then define:

struct x myvar;
myvar.a = 54;

You can be sure that myvar.a will hold 16 bits, and myvar.b will use 5; the total size of myvar rounding up for what all the bits comprise, plus of course the size of any other fields.

Peter
short is usually 16 bits, but long can be either 32 or 64 bits on modern systems. long long will almost always be 64.
David Thornley
David's right. If you go this route, I'd at least include something like "assert(sizeof (short) == 2)" somewhere in your code.
j_random_hacker
Longs in theory can be 64 bits. I've never worked with a 64 bit machine, but my impression has been most compilers still keep long at 32 and force you to use long long for 64. The tricky thing is, I think, this is all implementation-defined regardless of conventions.
Peter
+5  A: 

Boost has the typedefs for all of the C99 types and more: "Boost integer library"

Hrvoje Prgeša
+1  A: 

I've used a public domain (not GPL - true public domain) version of stdint.h by Danny Smith that's available in the mingw package:

I had to tweak that version to compile with some non VC 8 compilers (mostly VC6) - it has served me well.

Maybe one of these days I'll get around to posting my VC6-compatible version somewhere. The changes were pretty minor - just some macro trickery to use VC6 specific keywords for 64-bit types. If you don't need VC6 support, the mingw version should probably be all you need.

Michael Burr