Primitive Types

Like most languages, C++ comes with a small set of types that are built into the language. Almost every other type created and used in the language is some combination or composition of these types.

Size and Width

In C++, all types have an implicit property called width or size. This refers to how much memory; in bits or bytes, a given type maximally occupies. This leaves enough room for any value of the given type to fit in the allocated spot. The minimum size a type can occupy in C++ is 8-bits or a byte.

Integral Types

Integral types are the most basic kind of type in C++. These types represent whole numerical values of varying sizes. Some are used to represent logical values, other character code point and some are just plain old number types.

Boolean Type

The first type we will look at is bool. bool represents a Boolean value, meaning it is either true or false. This is a specialization of a unique type-function called a sum type. A sum type is a type that can hold one of its possible variants (also called 'appends' or 'injections'), in this case these are the type constructors true and false. However, in C++ bool is built-in to the language and thus these properties are hidden away.

bool occupies a memory space of 8-bits or a byte. It is also worth pointing out that true and false are literals (as they are built-in keywords) holding there respective values independently. Booleans are used to denote truthiness and logic in a programming language. In C++, bool can be implicitly promoted to another integral type such as int with false becoming 0 and true becoming 1. Other integral types also can be narrowed to a bool with 0 becoming false and anything else becoming true.

Character Types

The next type we will look is the char. This is C++ standard character type. These are values such as 'a' or even escape characters like '\n'. It holds only a single byte (same as bool) allowing it to represent \( 2^8 = 256 \) different values. Depending on the system is is either signed or unsigned, meaning either the leading bit is dedicated to the sign of the value or is another number point. Depending on the representation, char can have a value between 0..255 (unsigned) or -127..128 (signed). Character literals exclusively use single quotes in C++.

There is another character type in C++ called wchar_t. This is a 'wide character' which can hold more bits than the char type. On Windows systems it is 16-bits (2-bytes) while on Unix based systems (Linux, macOS etc.) this is typically 32-bits (4-bytes). This allows for wchar_t to be to store many more different codepoints. A wide character literal also uses single quotes however, the quote pair is prefixed with a 'L' eg. 'a' as a wchar_t literal looks like L'a'.

Like bool, char and wchar_t are integral types, this means that they are really numbers however, the system will treat them differently, eg. for IO.

Number Types

There is only one primary number type in C++ called int. This represents a (typically) 32-bit (4-byte), signed number. It can store \( 2^{32} = 4,294,967,296 \) values has a value range of -2'147'483'647..2'147'483'648. int is probably the most basic type in terms of bit layout in C++ with every bit storing data from the number with only the first bit indicating the sign of the number.

Float Point Types

C++ has two distinct floating point number types. These are float and double. float implements the IEEE-754 binary32 floating point format while double implements the IEEE-754 binary64 floating point format, hence the name double indicating double floating point precision.

Floating point numbers are a unique problem in computing. It is impossible to represent all precisions a decimal number can have (number of decimal places) which still being able to compute large numbers with limited memory. To tackle this, floating point numbers break up the bit-space of the floating point into the sign, fraction and exponents chapters. The IEEE-754 binary32 format uses 1-bit for the sign, 8-bits (a byte) for the exponent and and 23-bits (3-bytes - 1-bit) for the fraction. The IEEE-754 binary64 format has; again 1-bit for the sign, 11-bits for the exponent and 52-bits for the fraction chapter. This gives you (greater than) double the number bits you can use represent your fraction chapter or \( 536,870,912 \) times more possible values for the fraction chapter of a double over a float (\( 2^{52}=4.5035996\cdot10^{15} \) vs \( 2^{23}=8,388,608 \)).

Void

In C++ there is a unique type called called void. This is an incomplete and it can not be completed. It is a unique type of literal but it holds no value. void is used to indicate the absence of a return value (and input parameter value in C). It is different from the unit type (which is not explicitly present in C++) which has the type () and value (), void has the type of void but not the value of void. It has no value.

Nullptr

nullptr is a literal type which has type of std::nullptr_t and value of nullptr. This is a unique type used by pointers to indicate that they point to nothing.

Other Types

There are two more types in C++ that are worth talking about. These are std::size_t and std::ptrdiff_t. std::size_t is a platform dependent type that indicates the maximum possible size of an unsigned integer in C++. This is typically a 32-bit or 64-bit number types.

std::ptrdiff_t is a signed number type that is returned by subtracting two pointers in C++.

Auto

While C++ is a statically typed language, it is able to infer and deduce the types of many things at compile time. This is achieve with a non-type keyword called auto. While auto is used in many places that type specifiers are used (more on this in the next section), it is important to note that it itself is not a type but rather a automatic type, essentially a placeholder for the to-be deduced type.