As a result of a question someone asked us the other day, the issue arose of how much space the different variable types we use in programming really occupy. So I’m going to dedicate a post to talk a little about the topic.
Traditionally, in any programming course there is usually a slide explaining the sizes in bytes of the different available types of variables. As an introduction, it is usually sufficient.
But, obviously, if we are here it is because the answer is not so simple. In general, the size of the variables depends on the processor architecture, the operating system, and the compiler we are using.
But, instead of just talking or giving you a theoretical lecture, the best thing we can do is to illustrate and verify it with examples. To do this, we are going to measure the real size of the different variable types in different cases.
So, we are going to compare the size of variables in an Atmega328p (Arduino), an ESP32, a Raspberry Pi 3 (ARM32), and a x64 desktop computer with Windows 10 (MSC++ and G++) and Linux x64 (G++ on Ubuntu 20.04).
In case anyone wants to replicate the results, the code used is very simple. Thus, in the case of Arduino and ESP32 we will use,
void setup()
{
Serial.begin(115200);
}
void loop()
{
Serial.print("bool "); Serial.println(sizeof(bool));
Serial.print("char "); Serial.println(sizeof(char));
Serial.print("int "); Serial.println(sizeof(int));
Serial.print("long "); Serial.println(sizeof(long));
Serial.print("long long "); Serial.println(sizeof(long long));
Serial.print("float "); Serial.println(sizeof(float));
Serial.print("double "); Serial.println(sizeof(double));
Serial.print("long double "); Serial.println(sizeof(long double));
delay(10000);
}
While in the case of Raspberry Pi and Windows / Linux on a desktop computer, we will use
#include <iostream>
int main()
{
std::cout << "bool " << sizeof(bool) << "\n";
std::cout << "char " << sizeof(char) << "\n";
std::cout << "int " << sizeof(int) << "\n";
std::cout << "long " << sizeof(long) << "\n";
std::cout << "long long " << sizeof(long long) << "\n";
std::cout << "float " << sizeof(float) << "\n";
std::cout << "double " << sizeof(double) << "\n";
std::cout << "long double " << sizeof(long double) << "\n";
}
Here we have the results we obtain in the following table,
Type | atmega328p | esp32 | rpi 3 arm32 | Win x64 x64 MSC++ | Win x64 G++ | linux x64 g++ |
---|
| bool | 1 | 1 | 1 | 1 | 1 | 1 | | char | 1 | 1 | 1 | 1 | 1 | 1 | | int | 2 | 4 | 4 | 4 | 4 | 4 | | long | 4 | 4 | 4 | 4 | 4 | 8 | | long long | 8 | 8 | 8 | 8 | 8 | 8 | | float | 4 | 4 | 4 | 4 | 4 | 4 | | double | 4 | 8 | 8 | 8 | 8 | 8 | | long double | 4 | 8 | 8 | 8 | 16 | 16 |
We see that, in the case of the Atmega328p (Arduino), the results are most similar to what is “traditionally” explained when teaching variable sizes in C++. Thus, we see that an int in this case is 2 bytes, long 4 bytes, and long long 8 bytes. On the other hand, in floating point, all the variables are 4 bytes. So there is “really” no double.
If we go to the ESP32, we see that here both int and long are 4 bytes. The ESP32 is a 32-bit processor, so it takes the same “effort” to perform operations with 4 bytes. Therefore, the int type is not 2 bytes, but 4 bytes in reality. On the other hand, here the double of 8 bytes in floating point exists, but not the long double.
In the case of a Raspberry Pi, ARM32, with G++ compiler, we obtain exactly the same results as in the ESP32.
Regarding Windows, with G++ compiler, it is interesting to see that both int and long occupy 4 bytes, while long long is 8 bytes. In Linux, with the same compiler, the opposite occurs. Int is 4 bytes, while long and long long are both 8-byte variables.
On the other hand, in Windows with the MSC++ compiler (Visual Studio) the long double type is considered as an 8-byte variable. While G++ extends the size of long double to 16 bytes, both in Windows and in Linux.
As we can see, it is not so simple to answer what the size of variables in C++ is as is usually believed. In reality, it is full of nuances and details, and to answer it is necessary to know the architecture of the processor, the operating system, and the compiler that will be used.
And we haven’t even talked about the size of the pointers! Something we might talk about someday, but in any case, it will be in a future post. Until next time!