Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Checking an C-Array Size at Compile Time

4.56/5 (6 votes)
7 Jul 2011CPOL2 min read 18.2K  
Be sure that your array has the right size - without using size_of!
In this tip, you will learn how to check a C-array size at compile time

Introduction

Assume you have an array being initialized on declaration in the following form, but with many more entries:

C++
const char* arr[] =
{
    "One", 
    "Two", 
    "Three"
};

It must be made sure that the array has a certain size (maybe to fit an enumeration or for other reasons). Providing the number of elements to the array declaration is of limited help, as it would silently initialize any elements for which no value is given with 0. There will only be a compiler error if the initializer list is longer than the array.

The following code visualizes the vulnerability arising from this behavior:

C++
const char* arr2[3] =
{
    "One", 
    "Two"
    "Three"
};

While arr2 looks pretty okay, its real contents are:

C++
arr2[0] -> "One\0"<br />
arr2[1] -> "TwoThree\0"<br />
arr2[2] -> 0

(\0 visualizes the null-termination for C-strings - that's right there won't even be a null-value between "Two" and "Three".)

Using a reduced or empty initialization list is actually a pretty good trick, if you want to initialize an array with 0-values, but not helpful in this case. So, if you have an array that is initialized on declaration, it might be better not to specify its size directly but let the size be defined by the number of elements in the initializer list.

The array size can still be tested at compile time by the following function template:

C++
template<
    int test_len, 
    typename array_element, 
    int n>
inline void assert_array_size(array_element(& /* arr */)[n])
{
    // generate compile-time error if values mismatch:
    // (Static assertions provide a better alternative but
    // are not always available)
    int t[test_len == n];
    t[0] = 1;
}

This template causes a compiler error when the compile-time parameter test_len is different from the array size n automatically to be deducted from the function template parameter. In order to perform the test, a function or method needs to contain the following call to the function template.

C++
void f() {
    assert_array_size<3>(arr); // OK
    // assert_array_size<4>(arr); // Compiler Error
}

As the test still runs a compile-time, it is not even necessary to call f() at run-time.

Note: For this to work, the array declaration must not state the number of elements. If the array size was given there (in this example to 3), the array will have that size and the assertion result would be forced to success even if it is not initialized correctly.

History

  • 7th July, 2011: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)