C - Проверьте, назначено ли целое число - PullRequest
27 голосов
/ 04 августа 2009

Как определить, является ли целое число неназначенным?

int i; /* no assignment */

if (/* conditional statement here to check if int i is unassigned or not */) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

Ответы [ 12 ]

22 голосов
/ 04 августа 2009

Вы не можете. Он будет иметь «неопределенный» контент, то есть он будет содержать то, что когда-либо случалось в этом месте памяти.

. , , если я не объявлен в глобальной области видимости, он будет инициализирован нулем.

8 голосов
/ 04 августа 2009

C не поддерживает это по сути - так же, как и не поддерживает проверку границ массивов. Это компромисс между скоростью / эффективностью и безопасностью.

В общем ... инициализируйте ваши переменные.

6 голосов
/ 04 августа 2009

Это очень просто. Вы знаете, что он не назначен, потому что вы его не инициализировали.

4 голосов
/ 04 августа 2009

Как уже отмечали другие, вы не можете написать программу на C, которая определяет, не инициализирована ли одна из ее собственных переменных, и вы должны стремиться к тому, чтобы переменные всегда инициализировались.

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

  • Если ваша цель - убедиться, что личные данные инициализируются ровно один раз, обычным способом является защита их с помощью

    int i;
    static bool initialized = 0;
    
    ... 
    if (!initialized) {
      initialized = 1;
      i = ... i's initial value ...;
    }
    
4 голосов
/ 04 августа 2009

Вы можете запросить предупреждения компилятора, если используете неинициализированные значения.Однако они не совсем надежны - иногда вы получаете ложный положительный результат, когда DFA не такой умный, как вы надеетесь, и, возможно, случайные ложные отрицания (надеюсь, нет, но я ничего не обещаю).

Для GCC:

-Wuninitialized -O1

Если вы хотите написать условный код:

int a = 3;
int b;
int *p = (rand() > RAND_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah

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

4 голосов
/ 04 августа 2009

Если i является глобальным или статическим, его значение будет 0, в противном случае его значение может быть любым, и нет никакого способа узнать, является ли это мусором или нет.

1 голос
/ 04 августа 2009

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

Я предлагаю , а не , чтобы проверить это внутри кода. Поскольку это может вызывать предупреждения компилятора (переменная «i» используется до того, как ей было присвоено значение), вносить новые ошибки и имеет очень мало шансов на успех в средних и больших программах.

Лучшим методом является использование инструментов анализа статического кода (таких как QA / C или PCLint). Использование компилятора с высоким уровнем чувствительности к предупреждению является бесплатной опцией, с гораздо меньшим охватом, чем у специализированных инструментов.

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

Если вам нужна проверка во время выполнения, то вы можете начать с инициализации переменных до значения вне допустимого диапазона. Например, -1 для положительного значения в противном случае. Тогда вы можете проверить на

#define UNASSIGNED_VALUE -1
    static int number_of_apples = UNASSIGNED_VALUE;
    if (UNASSIGNED_VALUE == number_of_apples)
    {
       // error handling
    }

это не настоящая переменная «не инициализирован», но, по крайней мере, вы можете определить, были ли выполнены задания времени выполнения в допустимом диапазоне.

1 голос
/ 04 августа 2009

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

1 голос
/ 04 августа 2009

Обычно переменные устанавливаются в 0 библиотекой C, но не обязательно.

Но в принципе вы не можете. Присвойте им значение по умолчанию в определении, например:

int i = 0; /* Or what ever value you know won't be used elsewhere */

Затем, если вы запустите какой-то код и захотите проверить, было ли там установлено значение, вы можете сравнить его с вашим начальным значением.

0 голосов
/ 23 ноября 2012

В C # я бы использовал:

Nullable<int> i = null; /* null assignment */

if (i == null) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

Не уверен, что это переведет на C, хотя.

...