views:

579

answers:

7

I am aware that the specification of the C language does not dictate the exact size of each integer type (e.g., int).

What I am wondering is: Is there a way in C (not C++) to define an integer type with a specific size that ensures it will be the same across different architectures? Like:

typedef int8 <an integer with 8 bits>
typedef int16 <an integer with 16 bits>

Or any other way that will allow other parts of the program to be compiled on different architecture.

+13  A: 

C99, in stdint.h, defines types like int8_t and int16_t.

Martin v. Löwis
I believe there is a version that covers many other platforms that don't conform to C99 as well, but I'm not sure.
Chris Lutz
These are *optional* parts of the standard.
paxdiablo
MSVC doesn't like `<stdint.h>`. Not that I care, I stopped using it because of the horrible code-gen.
LiraNuna
That's interesting. Are you saying it doesn't have stdint.h or cstdint or that it doesn't have int16_t even though it supports a type with that bit width? That would, I think, make it non-conforming, and I doubt MS would be that stupid.
paxdiablo
I tried a few combinations of #include-ing stdint or cstdint but suprisingly VC9 could not find anything like that. Searching fo "stdint" in MSDN confirms that it's not there.
mxp
A public domain (not even a MIT/BSD license - you don't even need to keepa copyright attribution around) stdint.h for MSVC (a slightly modified version from MinGW): http://snipplr.com/view/18199/stdinth/
Michael Burr
@paxdiablo - `int8_t` and `int16_t` are optional, but only if the implementation doesn't actually have integer types with those widths.
Michael Burr
@paxdiablo: I agree with Michael Burr; stdint.h itself is not optional.
Martin v. Löwis
@paxdiablo: VC simply isn't C99 conform. (They don't even claim to be.) See http://stackoverflow.com/questions/1156267/ for `stdint.h` on VC.
sbi
+2  A: 

Unless you check for each platform with #ifdef or so, I doubt it's easily possible. But many libraries already do that task for you. For MSVC it's __int8, __int16, &c. The GTK library has similar typedefs.

Joey
+2  A: 

As far as I know the answer is no. We code for different platforms and we just use typedefs for the specific platforms using #if/#else. For example on Win32: typedef int int32;

Regards,

Sebastiaan

Sebastiaan Megens
+5  A: 

No, the C standard specifies minimum sizes for integral types but makes no guarantee on maximum sizes.

An implementation shall provide intN_t types if types of that size are available. I only mention that since you had a cross-platform tag - an implementation that does not have a type of the correct bit width does not need to provide those types.

You can generally select (with setting defines with, for example, cc -D_INT16_IS_INT and #ifdefs) the correct type to use for a specific bit size. You can work out the required defines for each platform you want to support with C code using CHAR_BIT and sizeof().

The relevant section of the c1x draft (n1362) is:


7.18.1.1 Exact-width integer types

  1. The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes a signed integer type with a width of exactly 8 bits.

  2. The typedef name uintN_t designates an unsigned integer type with width N. Thus, uint24_t denotes an unsigned integer type with a width of exactly 24 bits.

  3. These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.


Regarding the selection of types, something like this should suffice:

#ifdef INT32_IS_SHORT
    typedef short INT32
#endif
#ifdef INT32_IS_INT
    typedef int INT32
#endif
#ifdef INT32_IS_LONG
    typedef long INT32
#endif
paxdiablo
If you want to fail when the system doesn't have the exact size, then just use `int8_t` or `int16_t` - the build will fail if the system doesn't have them - no need for the conditional code. If you want to not fail but use the next best type instead, use int_least8_t or int_least16_t.
Michael Burr
The preprocessor can't evaluate `sizeof()`.
Chris Lutz
According to the C99 standard, long has to be more than 16-bits ;)
Joe D
Good point, Joe, fixed, even though I noticed the smiley :-) Michael, OP wanted the "program to be compiled on different architecture" so failing to compile probably isn't quite good enough, and they wanted "specific size" so next best type is probably not desired either.
paxdiablo
+11  A: 

What you want is <stdint.h>, which compilers that conform to the C standard ("C99") will implement. Unfortunately, this does not include Microsoft. Fortunately, an open-source project provides a <stdint.h> for Windows, see msinttypes.

This will allow you to use int32_t and uint32_t, plus 8, 16, and 64, and many others.

Note: the header file itself is not optional in the standard, however, most of the types in the header are individually optional. Some are not. The most commonly used types are the optional ones, but nothing stops you from using the required ones. The thing is, if an implementation provides the header at all, in practice they define all of the types.

DigitalRoss
Does this means that if I always compile my code with C99 compiler and always include <stdint.h>, I should be sure that int32_t is always 4 bytes?
NawaMan
@NawaMan - you can be sure that `int32_t` will have exactly 32-bits. If the platform doesn't have a 32-bit int type, the compile will fail as the `int32_t` type won't be defined. Also, many non-C99 compilers provide a `stdint.h` - for those that don't (Microsoft) you can get one from several place pointed to in other comments/answers including: http://snipplr.com/view/18199/stdinth/
Michael Burr
@NawaMan: YES. It should also be noted that C99 gives you minimums for the classical types: int >= 16, long >= 32, long long >= 64.
DigitalRoss
A: 

You could always write an arithmetic library that used vectors of unsigned char for the numbers. That way you could use numbers of whatever bit length you want, and even allow the bit length to vary.

Actually, you don't need to implement such a library because GNU MP handles this already.

http://gmplib.org/

Michael Dillon
+2  A: 

You might want to take a look at pstdint.h. It is a portable implementation of stdint.h, and does not require C99 compiler support.

Marcin Koziuk