views:

876

answers:

6

Unlike Java or C#, primitive data types in C++ can vary in size depending on the platform. For example, int is not guaranteed to be a 32-bit integer. Various compiler environments define data types such as uint32 or dword for this purpose, but there seems to be no standard include file for fixed-size data types.

What is the recommended method to achieve maximum portability?

+1  A: 

Define a type (e.g. int32) in a header file. For each platform use another #ifdef and make sure that in32 is a 32 bit integer. Everywhere in your code use int32 and make sure that when you compile on different platforms you use the right define

+1  A: 

Two things:

First, there is a header file called limits.h that gives lots of useful platform specific information. It will give max and min values for the int type for example. From that, you can deduce how big the int type is.

You can also use the sizeof operator at runtime for these purposes too.

I hope this helps . . .

K

Karl T.
+4  A: 

Create a header file called types.h, and define all the fixed-size primitive types you need (int32, uint32, uint8, etc.). To support multiple platforms, you can either use #ifdef's or have a separate include directory for each platform (include_x86, include_x86_64, include_sparc). In the latter case you would have separate build configurations for each platform, which would have the right include directory in their include path. The second method is preferable, according to the "The C++ Gotchas" by Stephen Dewhurst.

Just an aside, if you are planning to pass binary data between different platforms, you also have to worry about byte order.

Dima
+2  A: 

Part of the C99 standard was a stdint.h header file to provide this kind of information. For instance, it defines a type called uint32_t. Unfortunately, a lot of compilers don't support stdint.h. The best cross-platform implementation I've seen of stdint.h is here: http://www.azillionmonkeys.com/qed/pstdint.h. You can just include that in your project.

If you're using boost, I believe it also provides something equivalent to the stdint header.

Brian
A: 

There is a stdint.h header defined by the C99 standard and (I think) some variant or another of ISO C++. This defines nice types like int16_t, uint64_t, etc... which are guaranteed to have a specific size and representation. Unfortunately, it's availability isn't exactly standard (Microsoft in particular was a foot dragger here).

The simple answer is this, which works on every 32 or 64 bit byte-addressable architecture I am aware of:

  • All char variables are 1 byte
  • All short variables are 2 bytes
  • All int variables are 4 byte
  • DO NOT use a "long", which is of indeterminate size.
  • All known compilers with support for 64 bit math allow "long long" as a native 64 bit type.

Be aware that some 32 bit compilers don't have a 64 bit type at all, so using long long will limit you to 64 bit systems and a smaller set of compilers (which includes gcc and MSVC, so most people won't care about this problem).

Andy Ross
I have seen `int` as 64-bit on some platforms. `long long` is non-standard in C++ and is only guaranteed to be equal or greater size than `long`. `char`, on some rare systems, is 16-bit. These are not portable assumptions you're making. This is why so much software has trouble when ported to 64-bit from Win32 or Linux-32.
greyfade
This kind of response is why I started with the portable answer. But I'm sorry, your pedantry lacks evidence. I'm aware of no platform anywhere that defines int to 64 bits. "long long" is, indeed, non-standard. Yet amusingly it is far more portable across compilers than any standard 64 bit type; it saddens me that people fail to acknowledge this.The goal is portability, not standards. My answer was about practiacal portability concerns.
Andy Ross
+7  A: 

I found this header particularly useful: BOOST cstdint

Usually better than inventing own wheel (which incurs the maintenance and testing).

Anonymous