Fundamental Data Types

1. Predefined Data Types

Predefined data types.

Types Category Meaning
float
double
long double
Floating Point a number with a fractional part
bool Integral (Boolean) true or false
char
wchar_t (avoid, win bullshit)
char8_t (C++20) (these 3 for unicode)
char16_t (C++11)
char32_t (C++11)
Integral (Character) a single character of text
short int
long int
long long int (C++11)
Integral (Integer) positive and negative whole numbers
std::nullptr_t (C++11) Null Pointer a null pointer
void Void no type

In the context of C++, integral means 'like an integer' and includes bool and all the char types. This is because in memory they are stored the same as an integer.

1.1. Integers

An integer is an integral type that can represent positive and negative whole numbers, including 0:

Type Minimum Size Typical Size
short int 16 bits 16 bits
int 16 bits 32 bits
long int 32 bits 32 or 64 bits
long long int 64 bits 64 bits

In code, the types can be written with or without the suffix int, but the shorter version is preferred. #change

Signed and Unsigned Integers

By default, integers are signedm which means they can be negative and positive. Unsigned integers can be created with the unsigned keyword:

unsigned short a;
    

Unsigned integers are useful for networking #stub and systems with little memory, because unsigned integers can store more positive numbers without taking up extra memory, as no negative numbers are required.

Unexpected behaviour can happen when mixing signed and unsigned integers, as in operations the signed integer will be converted to an unsigned integer.

1.2. Floating point types

A float is a type than can hold a number with a fractional component.

Type Minimum Size Typical Size
float 32 bits 32 bits
double 64 bits 64 bits
long double 64 bits 64, 96, 128 bits

The literals for double include suffix . and the ones for float include suffix f.

[!note] Best Practice Use the correct literal for each type. Otherwise an useless conversion will happen.

1.3. Incomplete data types

An incomplete data type is a type that has been declared but not yet defined. The compiler knows about it's existence, but it doesn't know how much memory to allocate to it:

Incomplete types cannot be instantiated, but are used in different contexts.

2. Type and Object sizes

The C++ standard does not define the exact size of any fundamental types, only a minimum. However, on most standard systems they are the same:

Category Type Minimum Size Typical Size
Boolean bool 1 byte 1 byte
Character char
wchar_t
char8_t (C++20)
char16_t (C++11)
char32_t (C++11)
1 byte
1 byte
1 byte
2 bytes
4 bytes
1 byte
2 or 4 bytes
1 byte
2 bytes
4 bytes
Integral short
int
long
long long
2 bytes
2 bytes
4 bytes
8 bytes
2 bytes
4 bytes
4 or 8 bytes
8 bytes
Floating point float
double
long double
4 bytes
8 bytes
8 bytes
4 bytes
8 bytes
8, 12 or 16 bytes
Pointer std::nullptr_t 4 bytes 4 or 8 bytes

In order to determine the size of a type, we can use the sizeof operator. It does not work on dynamically allocated memory.

Types that use less memory aren't always faster. CPU's are often optimized to process data of a certain size (e.g. 32 bits), and types of that size may be processed quicker. #stub

2.2. Fixed-width integers

Sometimes, we need to use types that have an exact size, for this there are fixed-width integers.

Name Fixed Size
std::int8_t 1 byte signed
std::uint8_t 1 byte unsigned
std::int16_t 2 bytes signed
std::uint16_t 2 bytes unsigned
std::int32_t 4 bytes signed
std::uint32_t 4 bytes unsigned
std::int64_t 8 bytes signed
std::uint64_t 8 bytes unsigned

[!warning] std::int8_t and std::uint8_t typically behave like chars (e.g. when printing will display a char)

[!info] Fixed-width integers aren't actually new types, they are just aliases for existing predefined types. E.g. std::int32_t will be an alias for int on a 32bit system, but on a 16bit system it will be an alias for long instead. In most cases the 8 bit ones are an alias for signed and unsigned char, which is why they behave like one. Other implementations have a special one for 8 bit integers that behaves more like an integer.