Author: Chloé Lourseyre

If I’d come up with a pop quiz about sizes in C++, most C++ developers would fail it (I know I would), because sizes in C++ are complicated.

The size of every fundamental type is not fixed, they are always implementation-defined.

Sill, the standard defines constraints on these sizes. These constraints take the form of one of these:

• A comparison of the types’ `sizeof`.
• The type’s minimum number of bits.

## What is sizeof()?

One of the most widespread (and harmless) misconceptions about type sizes is that a byte holds 8 bits.

Although this is mostly true in practice, this is technically false.

A byte is actually defined as the size of a `char`. Though a `char` must have at least 8 bits, it can hold more. `sizeof(N)` returns the number of bytes of the type `N`, and every type size is expressed in terms of a `char` length. Thus, a 4-byte `int` is at least 32-bit, but you may not assume more from it (it could be 128-bit if a `char` is 32-bit).

The actual size of a byte is recorded in `CHAR_BIT`

## Summary of sizes in C++

Here are all the definitions and restrictions of fundamental types’ sizes in C++:

• 1 ≡ sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long)
• 1 ≤ sizeof(bool) ≤ sizeof(long)
• sizeof(char) ≤ sizeof(wchar_t) ≤ sizeof(long)
• sizeof(float) ≤ sizeof(double) ≤ sizeof(long double)
• sizeof(N) ≡ sizeof(unsigned N) ≡ sizeof(signed N)
• A char has at least 8 bits
• A short has at least 16 bits
• A long has at least 32 bits

… and nothing more.

Fun fact: according to this definition, it is technically possible that all fundamentals have 32 bits.

## Two words of wisdom

Since the sizes of the fundamental types entirely depend on the architecture, it may sometimes be hard to write consistent code.

### #include <limits>

`limits` of the standard library contains the upper and lower limits of every fundamental type, and allows you to know if a given type is signed or not.

Example:

```#include <limits>
#include <iostream>

int main()
{
std::cout << "largest double == " << std::numeric_limits<double>::max() << std::endl;
std::cout << "char is signed == " << std::numeric_limits<char>::is_signed << std::endl;
}
```

Reminder: signed integer overflow is undefined behavior. Using limits helps you in preventing that from happening.

### #include <cstdint>

Sometimes you may want to deal with fixed-sized types (in terms of bit) and not rely on the implementation specifics. For instance, if you implement serialization, work on very limited memory space, or develop cross-platform software, you may want to explicitly provide the bit-size of the type you’re using.

You can do so with the library `cstdint` which contains fixed-size types.

Here are a few of them:

## Wrapping up

If you want to read more about type size, refer to section §6.2.8 of The C++ Langage (Bjarne Stroustrup). More broadly, you can read about types and declarations in the whole section §6 of the book.

You can also refer to Fundamental types – cppreference.com for online documentation

Thanks for reading and see you next week!

Author: Chloé Lourseyre

Categories: UFO

## 6 thoughts on “About sizes”

1. std::cout << "char is signed == " << std::numeric_limits::is_signed << std::endl;
should it be ?

Like

1. thanks. I think what confused me is that the cout says “char” but the numeric limits says double. why is that?

Like