Discussion: Sizing Up Some Characters

Execute the code to understand the output and gain insights into array size determination and function parameter behavior.

Run the code

Now, it’s time to execute the code and observe the output.

Press + to interact
#include <iostream>
void serialize(char characters[])
{
std::cout << sizeof(characters) << "\n";
}
int main()
{
char characters[] = {'a', 'b', 'c'};
std::cout << sizeof(characters) << "\n";
std::cout << sizeof(characters) / sizeof(characters[0]) << "\n";
serialize(characters);
}

Understanding the output

The program defines a characters array with three elements. We then print the size of this array in various ways. What does the sizeof operator do in each case? Which of them are defined by the standard, and which are implementation-defined? And what do they print on the computer?

Defining the array

First, the program defines a char characters[] = {'a', 'b', 'c'} array. We then print the size of this array using the sizeof operator. The sizeof operator yields the number of bytes occupied by its operand, which in this case is 3, since each char is one byte, and there are three of them.

The sizeof() function

But wait, in the Aristotle’s Sum of Parts puzzle, we learned that the sizes of the fundamental types are not defined by the standard, so how can we be so sure that the answer is 3? A char could, after all, be 16-bit wide for all we know. As it turns out, sizeof(char) is defined to always return 1. So the byte that the C++ standard talks about isn’t necessarily eight bits wide but rather whatever width a char is.

Counting array elements

Next, we print sizeof(characters) / sizeof(characters[0]). This is the age-old idiom used to count the number of elements in an array in C or C++ and is guaranteed to print 3 in this puzzle. This is because sizeof(characters) returns 3 (as we just saw), and sizeof(characters[0]) is equivalent to sizeof(char), which always returns 1. As of C++17, we can also count the elements in an array with the new std::size() function template, which makes the code a bit simpler: std::cout << std::size(characters).

Serialization function

Finally, we want to serialize our characters, so we pass them to void serialize(char characters[]). The serialization function wants to know how large the array is for purposes of serialization and performs sizeof(characters), just like we do in main. But why does this print 8 and not 3? It’s because the type of the char characters[] parameter is actually not “array of char” but rather “pointer to char”!

The standard says the following about the types of function parameters:

After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”.

So the sizeof(characters) in the serialize function prints the size of a pointer rather than the size of an array since the type of characters is actually a “pointer to char” at this point. This is the implementation-defined part of the puzzle since the standard doesn’t define the size of a pointer. On most modern computers, a pointer is 64 bits, which equals 8 bytes. We probably see 8 printed.

Now, could we use the seemingly more powerful std::size() function template here, too, to get the actual number of elements in the array? We can’t, since characters is a pointer and not an array. The std::size() is only defined for collections and views with a .size() member function and for arrays. The std::size(characters) would fail to compile rather than give the wrong result, which is nice.

Recommendations

Here are some recommendations to improve the code’s safety and readability.

  • Use modern containers: Arrays in C++ are very limited, and when you pass them to functions, information like size is lost. Prefer types like std::vector or std::array instead.

  • Enable compiler warnings: Enable warnings in your project. GCC and Clang will both warn about the use of sizeof(characters) in serialize. Here’s GCC: warning: sizeof on array function parameter will return size of 'char *' instead of 'char[]'. At the time of writing, we couldn’t get MSVC to give us a warning about this.

Level up your interview prep. Join Educative to access 70+ hands-on prep courses.