Подтвердить что ты не робот

Не инициализированное целое значение всегда по умолчанию равно 0 в c?

Я читаю исходный код nginx и обнаруживаю, что он не инициализирует многие числовые переменные, включая ngx_int_t ngx_last_process;, здесь ngx_int_t, определяемый как long int

#if 0
    ngx_last_process = 0;
#endif

Итак, здесь @Игор Сысоев считает ненужным выполнять инициализацию?

Но в программе он принимает значение по умолчанию 0:

    for (s = 0; s < ngx_last_process; s++) {
        if (ngx_processes[s].pid == -1) {
            break;
        }
    }

Можно ли гарантировать, что не инициализированная переменная будет иметь значение 0 в c вообще?

4b9b3361

Ответ 1

По умолчанию внешние и статические переменные инициализируются нулем, это гарантировано. Автоматические и регистровые переменные, у которых нет явного инициализатора, будут иметь неопределенное значение (либо неопределенное значение, либо ловушечное представление).

Из стандарта:

C89

6.5.7

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

C99

6.2.4, §5:

Для такого объекта, который не имеет тип массива переменной длины, его время жизни продолжается от входа в блок, с которым он связан, до тех пор, пока выполнение этого блока не закончится в любом случае. (Ввод закрытого блока или вызов функции приостанавливается, но не заканчивается, выполнение текущего блока.) Если блок введен рекурсивно, новый экземпляр объект создается каждый раз. Начальное значение объекта является неопределенным. Если инициализация указана для объекта, она выполняется каждый раз, когда декларация достигнутый при выполнении блока; в противном случае значение становится неопределенным каждый время достижения декларации.

6.7.8, §10:

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

- если он имеет тип указателя, он инициализируется нулевым указателем;

     

- если он имеет арифметический тип, он инициализируется нулевым (положительным или неотображенным),

     

- если он является агрегатом, каждый член инициализируется (рекурсивно) в соответствии с этими правилами;

     

- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами.

3.17.2, § 1:

неопределенное значение: либо неопределенное значение, либо представление ловушки

3.17.3, §1:

неопределенное значение: действительное значение соответствующего типа, если настоящий международный стандарт не налагает никаких требований на то, какое значение выбрано в любом случае. ПРИМЕЧАНИЕ Неопределенное значение не может быть ловушечным представлением.

Ответ 2

automatic (локальные) переменные не гарантируются равными нулю, могут содержать мусор.

global переменные и переменные static гарантированы равными нулю.

Ответ 3

Объявленные переменные (как int) в области инициализируются на 0.

Пример

int i;
int main()
{
   int x;
   printf("%d",i); // prints 0
   printf("%d",x); // prints some unspecified value
}

Можно ли гарантировать, что не инициализированная переменная будет иметь значение 0 в c вообще?

Nopes! Это не выполняется для переменных, объявленных в области функций.

Ответ 4

Это зависит от того, как распределена переменная. Статически выделенные переменные инициализируются до нуля, тогда как переменные, выделенные в стеке или с помощью malloc(), не являются.