Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect an array definition againt incomplete initialization with non-zero values?

Tags:

c++

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.

like image 773
fork0 Avatar asked Jun 05 '13 19:06

fork0


People also ask

What happens when you partially initialize an array with values?

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.

Can you initialize an array with 0 elements?

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.

What would happen if we did not initialize the array to 0 in the fill () function?

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.

What will happen if you do not initialize value to an array?

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.


2 Answers

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.

like image 116
Collin Dauphinee Avatar answered Oct 14 '22 23:10

Collin Dauphinee


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;

update

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.

like image 29
Mooing Duck Avatar answered Oct 14 '22 22:10

Mooing Duck