Introduction
Assume you have an array being initialized on declaration in the following form, but with many more entries:
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:
const char* arr2[3] =
{
"One",
"Two"
"Three"
};
While arr2
looks pretty okay, its real contents are:
arr2[0] -> "One\0"<br />
arr2[1] -> "TwoThree\0"<br />
arr2[2] -> 0
(\0
visualizes the null
-termination for C-string
s - 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:
template<
int test_len,
typename array_element,
int n>
inline void assert_array_size(array_element(& )[n])
{
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.
void f() {
assert_array_size<3>(arr); }
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