1.12. C++ Simple Types

[ fromfile: cppintro.xml id: simpletypes ]

The simple types supported in C/C++ are listed in table Table 1.2.

C/C++ also provides a special symbol that signifies the absence of type information: void.

C++ simple types can (variously) be modified by the following keywords to produce other simple types.

Table 1.2. Simple Types Hierarchy

byte/char typesintegral types floating point types
bool short int float
char unsigned short double
signed char intlong double
unsigned char unsigned int
wchar_t anyType*
long int
unsigned long

C++ compilers allow you to omit “int“ from the type names short int, long int, and unsigned int. You can also omit signed from most types, since that is the default.

C++ Object Size

Object size in C++ is expressed in terms of the size of char. In this metric, the size of char is 1. Since the range of values for a particular type depends on the underlying architecture of the machine on which the compiler is running, the ANSI/ISO standard for C++ does not specify the size of any of the types displayed in Table 1.2. It only guarantees that a given type (e.g., int) must not be smaller than one that appears above it (e.g., short) in the table.

There is a special operator sizeof() which returns the number of char-sized memory cells that a given expression requires for storage. On most systems, a single char is is stored as an 8-bit byte. Unlike most functions, the sizeof() operator can take arguments that are value expressions or type expressions. Example 1.15 shows how sizeof() can be used, and some of the values it returns on a 32-bit x86 system.

Example 1.15. src/early-examples/size/qsize.cpp

#include <QString>
#include <QTextStream>
//#include <QChar>

int main() {
    QTextStream cout(stdout);
    char array1[34] = "This is a dreaded C array of char";
    char array2[] = "if not for main, we could avoid it entirely.";
    char* charp = array1; 1
    QString qstring = "This is a unicode QString. Much preferred." ;
    Q_ASSERT (sizeof(i) == sizeof(int));
    cout << "  c type sizes: \n";
    cout << "sizeof(char) = " << sizeof(char) << '\n';
    cout << "sizeof(wchar_t) = " << sizeof(wchar_t) << '\n';
    cout << "sizeof(int) = " << sizeof(int) << '\n';
    cout << "sizeof(long) = " << sizeof(long) << '\n';
    cout << "sizeof(float) = " << sizeof(float) << '\n';
    cout << "sizeof(double) = " << sizeof(double) << '\n';
    cout << "sizeof(double*) = " << sizeof(double*) << '\n';
    cout << "sizeof(array1) = " << sizeof(array1) << '\n';
    cout << "sizeof(array2) = " << sizeof(array2) << '\n';
    cout << "sizeof(char*) = " << sizeof(charp) << endl;
    cout << "  qt type sizes: \n";  
    cout << "sizeof(qstring) = " << sizeof(qstring) << endl;
    cout << "sizeof(qint32) = " << sizeof (qint32) << "\n"; 2
    cout << "sizeof(qint64) = " << sizeof(qint64) << '\n'; 3
    cout << "sizeof(qchar) = " << sizeof (QChar) << endl;  4
    cout << "qstring.length() = " << qstring.length() << endl; 5
    return 0;
}

Output:

c type sizes: sizeof(char) = 1 sizeof(wchar_t) = 4 sizeof(int) = 4 sizeof(long) = 4 sizeof(float) = 4 sizeof(double) = 8 sizeof(double*) = 4 sizeof(array1) = 34 sizeof(array2) = 45 sizeof(char*) = 4 qt type sizes: sizeof(qstring) = 4 sizeof(qint32) = 4 sizeof(qint64) = 8 sizeof(qchar) = 2 qstring.length() = 42

1

pointer to first element of array

2

guaranteed to be 32 bits on all platforms

3

guaranteed to be 64 bits on all platforms

4

twice as big as a char

5

for # of bytes, be sure to take into account the size of QChar

Notice that all pointers are the same size, regardless of their type.

In the output, we can see that sizeof(qstring) is only 4 bytes, but it is a complex class that uses dynamic memory, so we must call length() to get the number of QChar in the string. Since a QChar is twice the sizeof(char), we need to double the length to compute the actual size of qstring in memory. Under the covers, QString shares memory with other strings that have the same value, so after a copy, the dynamic memory does not 'belong' exclusively to one QString object.

The ranges of values for the integral types (bool, char, int) are defined in the standard header file limits.h. On a typical *nix installation that file can be found in a subdirectory of /usr/include.



[7] For further discussion of the differences between signed an unsigned integral types, see Section 19.4.