tags:

views:

28983

answers:

18

I'm looking for detailed informations regarding the size of basic C++ types.

I know that it depends on the architecture (16 bits, 32 bits, 64 bits) and the compiler.

But are there any standards ?

I'm using Visual Studio 2008 on a 32 bit achitecture. Here is what I get :

char   : 1 byte
short  : 2 bytes
int    : 4 bytes
long   : 4 bytes
float  : 4 bytes
double : 8 bytes

I tried to find, without much success, reliable informations telling the sizes of char, short, int , long, double, float (and other types I don't think of) under different architecture and compiler.

A: 

As mentioned the size should reflect the current architecture. You could take a peak around in limits.h if you want to see how your current compiler is handling things.

-John

John T
Thanks, but I would like to know the sizes for achitectures I don't have myselft (like 64bits).This tutorial only talk about 32bits achitectures...
Jérôme
+24  A: 

In practice there's no such thing. You can expect std::size_t to always represent the unsigned native integer size on current architecture. i.e. 16-bit, 32-bit or 64-bit.

But as far as all the other built-in types go, it really depends on the compiler. Here's two excerpts taken from the current working draft of the latest C++ standard:

There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list.

For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int, and unsigned long long int, each of which occupies the same amount of storage and has the same alignment requirements.

If you want to you can statically (compile-time) assert the sizeof these fundamental types. It will alert people to think about porting your code if the sizeof assumptions change.

John Leidegren
good post. another thing that's required is the following least bit-sizes (documented in c89 / c99 together with limits.h and taken over by c++): char >=8, short and int >=16, long >=32 .
Johannes Schaub - litb
@Hosam Aly - Thanks for quoting that part, didn't think of it.
John Leidegren
@John, you're welcome.
Hosam Aly
A: 

16-bit

32-bit

64-bit

kitchen
Thanks, but I would like to know the sizes for achitectures I don't have myself (like 64bits).This tutorial only talks about 32bits achitectures...
Jérôme
I've updated it with more information. Hope it helps.
kitchen
A: 

As you mentioned - it largely depends upon the compiler and the platform

check herefor the ANSI standard http://home.att.net/~jackklein/c/inttypes.html

Here is the one for microsoft compiler http://msdn.microsoft.com/en-us/library/s3f49ktz(vs.71).aspx

atVelu
+1  A: 

There is a standard and it is specified in the various standards documents (ISO, ANSI and whatnot).

Wikipedia has a great page explaining the various types and the max they may store: Integer in Computer Science.

However even with a standard C++ compiler you can find out relatively easily using the following code snippet:

#include <iostream>
#include <limits>


int main() {
    // Change the template parameter to the various different types.
    std::cout << std::numeric_limits<int>::max() << std::endl;
}

Documentation for std::numeric_limits can be found at Roguewave. It includes a plethora of other commands you can call to find out the various limits. This can be used with any arbitrary type that conveys size, for example std::streamsize.

John's answer contains the best description, as those are guaranteed to hold. No matter what platform you are on, there is another good page that goes into more detail as to how many bits each type MUST contain: int types, which are defined in the standard.

I hope this helps!

X-Istence
+5  A: 

Nope, there is no standard for type sizes. Standard only requires that:

sizeof(short int) <= sizeof(int) <= sizeof(long int)

The best thing you can do if you want variables of a fixed sizes is to use macros like this:

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

Then you can use WORD to define your variables. It's not that I like this but it's the most portable way.

happy_emi
The problem is that WORD gets spread around the program into areas that are not truly dependent on a fixed size (look at some windows code). As I found out when moving from a 16 bit to 32 bit system you end up with the same problem that WORD was meant to solve.
lilburne
@liburne Of course you should use WORD only when you need a fixed size variable, like when you are reading/writing from/to a file. If a piece of code is not really dependent from a fixed size, then you should use normal "int" variables.
happy_emi
Also, 1 = sizeof(char) <= sizeof(short int) <= ...
Drew Hall
+15  A: 

If you need fixed size types uses types like uint32_t (unsigned integer 32bits) defined in stdint.h, they are specified in c99.

Ben
They are specified but not required.
dreamlax
+14  A: 

The standard does not specify the size in bytes, but it specifies minimum ranges that various integral types must be able to hold. You can infer minimum size in bytes from it.

Minimum ranges guaranteed by the standard (from "Integer Types In C and C++"):

  1. signed char: -127 to 127
  2. unsigned char: 0 to 255
  3. "plain" char: -127 to 127 or 0 to 255 (depends on default char signedness)
  4. signed short: -32767 to 32767
  5. unsigned short: 0 to 65535
  6. signed int: -32767 to 32767
  7. unsigned int: 0 to 65535
  8. signed long: -2147483647 to 2147483647
  9. unsigned long: 0 to 4294967295
  10. signed long long: -9223372036854775807 to 9223372036854775807
  11. unsigned long long: 0 to 18446744073709551615

Actual platform-specific range values are found in <limits.h>

Alex B
+3  A: 

For 32-bit systems, the 'de facto' standard is ILP32 - that is, int, long and pointer are all 32-bit quantities.

For 64-bit systems, the primary Unix 'de facto' standard is LP64 - long and pointer are 64-bit (but int is 32-bit). The Windows 64-bit standard is LLP64 - long long and pointer are 64-bit (but long and int are both 32-bit).

At one time, some Unix systems used an ILP64 organization.

None of these de facto standards is legislated by the C standard (ISO/IEC 9899:1999), but all are permitted by it.

And, by definition, sizeof(char) is 1, notwithstanding the test in the Perl configure script.

Note that there were machines (Crays) where CHAR_BIT was much larger than 8. That meant, IIRC, that sizeof(int) was also 1, because both char and int were 32-bit.

Jonathan Leffler
+1  A: 

For floating point numbers there is a standard (IEEE754): floats are 32 bit and doubles are 64. This is a hardware standard, not a C++ standard, so compilers could theoretically define float and double to some other size, but in practice I've never seen an architecture that used anything different.

Crashworks
However, compliance with IEEE 754 (aka IEC 559) is optional within C++ (probably C too, but I'm not sure). See std::numeric_limits::is_iec559.
Drew Hall
A: 

My first question to you would be why does your program care? In the past 20 years I can count on one hand the number of times I depended on an exact number of bits. You might want to put in a check to see if you have enough precision, but of 32 bits is enough, your code should work fine with 64 bits as well.

KeithB
+3  A: 

You ask are there standards for these things? Well the TR1 C++ extension library adopts the types from C99. I believe these types will get brought into the C++0x standard. When that happens you can rely on the types like:

  • long long int
  • unsigned long long int

And the "sized" types from

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (and the unsigned counterparts).

Plus you get:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • Plus the unsigned counterparts.

These types represent the smallest integer types with at least the specified number of bits. Likewise there are the "fastest" integer types with at least the specified number of bits:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Plus the unsigned versions.

What "fast" means, if anything, is up to the implementation. It need not be the fastest for all purposes either.

For more information, see the TR1 spec or Pete Becker's book "The C++ Standard Library Extensions".

Brian Neal
A: 

1) Table N1 in article "The forgotten problems of 64-bit programs development"

2) "Data model"

A: 

In addition to Brian Neal's answer, see also my answer to the stackoverflow question: What is the difference between an int and a long in C++?

Roger Nelson
A: 

You can use variables provided by libraries such as OpenGL, Qt etc.

For example, Qt provides qint8 (guaranteed to be 8-bit on all platforms supported by Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.

Lawand
+1  A: 

There is standard.

C90 standard requires that

sizeof(short) <= sizeof(int) <= sizeof(long)

C99 standard requires that

sizeof(short) <= sizeof(int) <= sizeof(long) < sizeof(long long)

Here is the C99 specifications. Page 22 details sizes of different integral types.

Here is the int type sizes (bits) for Windows platforms:

Type        C99 Minimum       Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

If you are concerned with portability, or you want the name of the type reflects the size, you can look at the header <inttypes.h>, where the following macros are available:

int8_t
int16_t
int32_t
int64_t

int8_t is guaranteed to be 8 bits, and int16_t is guaranteed to be 16 bits, etc.

yinyueyouge
+3  A: 

It sounds to me like what the op is asking for is something like a table that looks like

            | GNU    | MSVC   | Borland| Comeau |
            |        |        |        |        |
------------|-------------------------------------------      
    char    |  ??    |  ??    |  ??    |  ??    |
    short   |  ??    |  ??    |  ??    |  ??    |
    int     |  ??    |  ??    |  ??    |  ??    |
    long    |  ??    |  ??    |  ??    |  ??    |
            |        |        |        |        |
    pointer |  ??    |  ??    |  ??    |  ??    |
            |        |        |        |        |
    float   |  ??    |  ??    |  ??    |  ??    |
    double  |  ??    |  ??    |  ??    |  ??    |

Does anyone know of anywhere that someone has put something like that together?

cheshirekow
this would have to be expanded a LOT as some of those compilers (if not all) can target multiple platforms, plus, i'm sure you have missed plenty of c++ compilers. Also, there is no guarantee that the compiler writers won't change the sizes themselves (though this would probably be a bad move on their part)
Grant Peters
A: 

The C++ Standard says it like this :

3.9.1, §2 :

There are five signed integer types : "signed char", "short int", "int", "long int", and "long long int". In this list, each type provides at least as much storage as those preceding it in the list. Plain ints have the natural size suggested by the architecture of the execution environment (44); the other signed integer types are provided to meet special needs.

(44) that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header <climits>.

The conclusion : it depends on which architecture you're working on. Any other assumption is false.

Jérôme Radix