Простой способ проверить, не инициализирован ли примитив?

Насколько я понимаю, в C такие примитивы, как int и float, инициализируются 0 при первом объявлении. То же самое верно, если объявлена ​​структура, содержащая примитивы. У меня возникли проблемы с поиском простого способа проверить, не инициализированы ли примитивы.

Например, предположим, что у меня есть переменная экземпляра типа int, объявленная в заголовочном файле. Мне нужно использовать эту переменную в моем коде реализации, и мне важно знать, было ли это значение инициализировано или нет. Проверка нуля на самом деле не вариант, потому что, если это значение действительно должно быть нулем, я повторно инициализировал значение, которое уже было изменено. Проверка на NULL также не сработает, потому что это не указатель.

Единственное решение, которое я придумал, — это инициализировать переменную в первом фрагменте исполняемого кода некоторым значением, которое, как я знаю, никогда не будет иметь отношения к остальной части программы. Например, если значение никогда не должно быть ниже нуля, я инициализирую его значением -1, чтобы знать, что оно еще не инициализировано. Однако это кажется очень грубым и может вызвать проблемы, если диапазон значений, которым может быть присвоена переменная, изменится.

Любые интересные предложения для такого рода проблемы? Заранее спасибо!


person dkaranovich    schedule 10.01.2011    source источник
comment
Использование неинициализированной переменной является UB. Если вы передадите переключатель -Wall (gcc), вы сможете отслеживать все неинициализированные переменные. gcc сообщит что-то вроде этого: ddd.c:8: warning: ‘i’ is used uninitialized in this function   -  person Francesco Laurita    schedule 10.01.2011


Ответы (3)


Ваше понимание неверно. Локальные переменные не инициализируются независимо от того, являются ли они int или float.

Только static переменных инициализируются нулем. Вы должны инициализировать все перед использованием. Даже если вы чувствуете, что ваша реализация инициализирует переменную, не стоит на это полагаться. Стандарт ничего не гарантирует. Использование неинициализированной переменной является неопределенным поведением.

person mmx    schedule 10.01.2011
comment
Спасибо, что поправили меня, но это не ответ на мой вопрос. Что именно я должен инициализировать свою переменную экземпляра, если ее значение не будет присвоено до какой-то более поздней процедуры? Как мне проверить, инициализирован он или не инициализирован в других процедурах? - person dkaranovich; 15.01.2011
comment
@Zanneth: Вы вообще не должны проверять саму переменную. Вы всегда должны инициализировать свои переменные перед использованием. Если вам по какой-то причине приходится полагаться на какой-то механизм отложенной инициализации, вы должны оставить флаг (либо в той же переменной со значением, например -1, если оно выходит за пределы диапазона допустимых значений, либо с отдельным логическим флагом, который отслеживает инициализацию переменной). - person mmx; 15.01.2011

Только глобальные примитивы, указатели и структуры данных инициализируются нулем; локальные переменные или malloc() память не являются.

person Aaron Digulla    schedule 10.01.2011

Нет никакой разницы между нулем, которым инициализируется объект со статической продолжительностью хранения, и нулем, который явно установлен в вашем коде. Ноль - это просто ноль.

Все, что вы можете сделать, это явно инициализировать его ненулевым недопустимым числом (в файле .c, который его определяет):

фу.ч:

extern double foo;

foo.c:

double foo = NAN;

Или, в качестве альтернативы, сопроводите его переменной флага, которая указывает, было ли оно инициализировано:

фу.ч:

extern double foo;
extern int foo_initialised;

foo.c:

double foo;
int foo_initialised;
person caf    schedule 10.01.2011