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

Инициализация глобальной и статической переменных в 0 всегда не нужна?

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

Здесь мой вопрос: неинициализированные глобальные и статические переменные переходят в сегмент BSS в программе. Итак, так называемый 0 должен быть all-bit 0.

Для интегральных переменных all-bit 0 будет оцениваться как 0. Переменные с плавающей запятой, если следующий IEEE 754, также 0.0. Но для указателей нулевые указатели необязательно должны быть all-bit 0, поэтому инициализация глобального указателя выглядит так:

int* p = NULL;

имеет значение только:

int *p;
4b9b3361

Ответ 1

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

Эта же основная идея относится и к типам с плавающей запятой и целыми числами - они также могут быть инициализированы до 0 или 0,0. Реализация может оставить это в том, что BSS устанавливает все биты в 0 тогда и только тогда, когда "знает", что это приведет к правильным значениям.

Ответ 2

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

Причина, по которой такие переменные могут перейти в сегмент BSS на определенной платформе, такова, что на целевой платформе нулевой указатель действительно представлен шаблоном с полным битом. То есть инициализация all-bits-zero для указателей просто работает правильно на этой платформе, поэтому компилятор использует BSS как самый простой и эффективный способ реализации правильного поведения на этой конкретной платформе. Если это не так, компилятору придется инициализировать такие статические переменные по-разному.

Это применимо к значениям с плавающей запятой, например, если на какой-либо платформе используется представление, отличное от IEEE 754, для таких значений с ненулевым битовым шаблоном для представления 0.0 (C не имеет мандата IEEE 754).

(Более того, это даже использовалось для всех интегральных типов, больших, чем char, пока один из TC для стандарта C99 окончательно не потребовал, чтобы шаблон all-bits-zero был допустимым представлением объекта для целых нулей всех типов на все платформы C.)

Хороший пример из реальной жизни исходит из С++ (в данном случае это другой язык, но актуальный). С++ обеспечивает ту же гарантию для скалярных переменных со статической продолжительностью хранения. Между тем, во многих популярных реализациях С++ используется значение 0xFFFFFFFF для представления нулевых указателей типа типа указателя на данные. Например.

SomeType SomeClass::*p = 0;

фактически преобразуется в код, который заполняет p шаблоном all-bits-one. Таким образом, если вы объявляете статическую переменную такого типа без явного инициализатора, компилятор должен будет убедиться, что его начальное значение является шаблоном "все-бит-один", а не паттерном "all-bits-zero". Некоторые компиляторы, как известно, ошибаются, помещая такие переменные в BSS, забывают о них, оставляя таким образом переменные, заполненные шаблоном с нулевым числом.