2015-08-29 2 views
1

Очень коротко: Как я могу включить предупреждение в НКУ и/или VS для кодов, таких как:Issue предупреждение о неправильном размере списка initialiizer статического массива

const int array[4] = {1, 2}; 

Longer версии: У меня есть таблица с постоянными свойствами , В основном он определяет, как взаимодействуют 2 «объекта». Для этого у меня есть таблица, которая имеет 3 измерения: среда, 1-й объект, 2-й объект. Существуют 3 различных среды (перечисление) и ~ 20 объектов. Таким образом, массив выглядит следующим образом:

const int property[3][20][20] = {{{...}}, {{...}}, {{...}}}; 

(В реальном коде 3 и 20 являются фактические счета константы перечислимого Можно также сделать ИНТ перечисление, но это еще не точка..)
Так доступ свойства [e] [t1] [t2] означает: как я должен обрабатывать встречу t1-> t2 в среде e? Заметим, что это вообще отличается от t2-> t1!

На самом деле, я бы предпочел переключиться на предупреждения о неиспользуемых членах перечисления, но в этом случае коммутатор будет в 3 раза вложенным и, следовательно, довольно подробным/огромным.

Если кто-нибудь может придумать что-нибудь лучше, я возьму его. До тех пор мне хотелось бы хотя бы предупредить, если я пропущу, чтобы заполнить элемент массива.

+0

-Wmissing-fi инициализаторы полей? (см. [на этой странице] (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)) – Caninonos

+1

@Caninonos Нет, это массивы, а не поля в структурах. – dasblinkenlight

+0

@ dasblinkenlight Действительно, я думал, что это сработает для обоих, но я не знаю. – Caninonos

ответ

3

Поставка меньшего количества инициализаторов, чем размер массива, является широко используемой функцией. Написание кода, который выглядит следующим образом:

int array[100] = {0}; 

является обычным способом инициализации всех элементов массива по умолчанию. В настоящее время gcc не предлагает переключатель для предупреждения об этой проблеме.

Один из способов, который работает только для массивов верхнего уровня будет использовать static_assert и удалить явный размер, например:

const int array[] = {1, 2, 3, 4}; 
//    ^^ 
//  No explicit size 

// Check the size here: 
static_assert(sizeof(array)/sizeof(array[0]) == 4, "Expected four elements"); 

Таким образом, вы получите ошибку компиляции, если число инициализаторы для массива не равны числу, которое вы ожидаете (т.е. четыре).

+0

Я (в настоящее время) не могу использовать C++ 11, к сожалению. И я прав, что это не сработает для 3D-случая? – Flamefire

+0

@Flamefire Это будет работать только для верхнего уровня 3D-футляра.Второй и третий уровни останутся неконтролируемыми, хотя, если вы не напишите для них индивидуальные проверки (это удвоит усилия и будет сложнее, чем проверка размеров вручную). – dasblinkenlight

3

Вы можете создать тонкую оболочку int, дать ей конструктор и использовать массивы этого типа обертки. Это не только даст вам предупреждение, но даже об ошибке:

struct Integer 
{ 
    Integer(int i) : i(i) {} 
    int i; 
}; 

int main() 
{ 
    const Integer array[4] = {1, 2}; 
} 

VC ошибка:

error C2073: 'array' : elements of partially initialized array must have a default constructor 

ошибка GCC:

error: no matching function for call to 'Integer::Integer(<brace-enclosed initializer list>)' 

Если использовать это решение, то вы могли бы также рассмотрите оператора конверсии:

struct Integer 
{ 
    Integer(int i) : i(i) {} 
    int i; 
    operator int() const { return i; } 
}; 

void f(int x) {} 

int main() 
{ 
    const Integer array[4] = {1, 2, 3, 4}; 
    f(array[0]); 
} 
Смежные вопросы