I have a global array, which is indexed by the values of an enum, which has an element representing number of values. The array must be initialized by a special value, which unfortunately is not a 0.
enum {
A, B, C, COUNT
};
extern const int arr[COUNT];
In a .cpp file:
const int arr[COUNT] = { -1, -1, -1 };
The enum is occasionally changed: new values added, some get removed. The error in my code, which I just fixed was an insufficient number of initialization values, which caused the rest of the array to be initialized with zeroes. I would like to put a safeguard against this kind of error.
The problem is to either guarantee that the arr
is always completely initialized with the special value (the -1
in the example) or to break compilation to get the developers attention, so the array can be updated manually.
The recent C++ standards are not available (old ms compilers and some proprietary junk). Templates can be used, to an extent. STL and Boost are strongly prohibited (don't ask), but I wont mind to copy or to reimplement the needed parts.
If it turns out to be impossible, I will have to consider changing the special value to be 0, but I would like to avoid that: the special value (the -1
) might be a bit too special and encoded implicitly in the rest of the code.
I would like to avoid DSL and code generation: the primary build system is jam on ms windows and it is major PITA to get anything generated there.
If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type. The same applies to elements of arrays with static storage duration.
The array will be initialized to 0 in case we provide empty initializer list or just specify 0 in the initializer list. Designated Initializer: This initializer is used when we want to initialize a range with the same value.
Even if you do not initialize the array, the Java compiler will not give any error. Normally, when the array is not initialized, the compiler assigns default values to each element of the array according to the data type of the element.
If the array is not initialized at the time of declaration or any time after that then it will contain some random values in each memory position.
The best solution I can come up with is to replace arr[COUNT]
with arr[]
, and then write a template to assert that sizeof(arr) / sizeof(int) == COUNT
. This won't ensure that it's initalized to -1
, but it will ensure that you've explicitly initialized the array with the correct number of elements.
C++11's static_assert
would be even better, or Boost's macro version, but if you don't have either available, you'll have to come up with something on your own.
This is easy.
enum {
A, B, C, COUNT
};
extern const int (&arr)[COUNT];
const int (&arr)[COUNT] = (int[]){ -1, -1, -1};
int main() {
arr[C];
}
At first glance this appears to produce overhead, but when you examine it closely, it simply produces two names for the same variable as far as the compiler cares. So no overhead.
Here it is working: http://ideone.com/Zg32zH, and here's what happens in the error case: http://ideone.com/yq5zt3
prog.cpp:6:27: error: invalid initialization of reference of type ‘const int (&)[3]’ from expression of type ‘const int [2]’
For some compilers you may need to name the temporary
const int arr_init[] = { -1, -1, -1};
const int (&arr)[COUNT] = arr_init;
I've been informed the first =(int[]){-1,-1,-1}
version is a compiler extension, and so the second =arr_init;
version is to be preferred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With