2017-01-26 32 views
2

С 6.7.8.10 в стандарте C99:Гарантировано ли, что глобальные переменные всегда инициализируются до 0 с помощью c99?

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

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

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

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

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

Является глобальной переменной любого типа (массив, структура, бит), которая всегда определяется как static storage?

+1

Да, насколько они хранятся в 'bss' секции. – LPs

+0

О! В этом-то и дело. Как я могу убедиться, что он находится в разделе 'bss'? – nowox

+2

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

ответ

2

Да. Это гарантировано (по крайней мере, с C89). «Глобальные переменные» (с внутренней или внешней связью) имеют статический срок хранения. Любой объект со статическим хранилищем гарантированно инициализируется нулем в соответствии с C99, 6.7.8 Инициализация.

C99 draft, 6.2.4 Storage durations of objects:

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

6.2.2 Linkages of identifiers описывает связь идентификаторов, в частности, по отношению к «глобальному» переменной:

3 Если объявление идентификатора области видимости файла для объекта или функции содержит класс Storage- спецификатор статического , идентификатор имеет внутреннюю связь.22)

4 Идентификатор, объявленный с помощью спецификатора класса хранения extern в области видимости, в которой отображается предварительное объявление этого идентификатора, 23), если предыдущее объявление указывает внутреннюю или внешнюю связь , связь идентификатора при t он позже объявляет то же самое, что и ссылка, указанная в предыдущем объявлении. Если ни одно предварительное объявление не отображается, или если в предыдущем объявлении не указана ссылка, то идентификатор имеет внешнюю привязку.

Игнорирует случай, который could lead to undefined behaviour, все идентификаторы области файла с внутренней или внешней связью, и все они имеют статическую продолжительность хранения.

0

Да, насколько они хранятся в разделе bss.

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

BTW - это код запуска, который отвечает за нуль раздела. Если вы работаете с нестандартными платформами или ваш код запуска сделан вами, вы должны это сделать.

+4

Действительно ли это часть стандарта C? Я не мог найти 'bss' в моей копии C99.Хотя 'bss' определенно является часто используемым именем, оно, похоже, не указано официально. – Gerhardh

+0

@ Герхард не стандартный юрист, но это способ предоставить стандарт. Ответ Влада указывал на стандартное требование. – LPs

+3

Раздел, в котором хранится глобальная переменная, не имеет никакого отношения к тому, будет ли пользователь, по-видимому, инициализироваться на '0'. Единственное, что имеет значение, это гарантии, которые дает стандарт C здесь. Как определенная платформа достигает этого, не должен быть бизнес программистом С. –

2

В соответствии со стандартом C (5.1.2 Исполнение сред)

1 Tw исполнение O среды являются де определены: Свободностоящая и размещение. В оба случая, запуск программы происходит, когда назначенная функция C - это , вызываемая средой выполнения. Все объекты со статическим хранилищем длительность должна быть инициализирована (установлена ​​на их начальные значения) до запуска программы . Способ и время такой инициализации: в противном случае не определено. Окончание программы возвращает управление в среду выполнения .

и (6.2.4 хранение длительности объектов)

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

3

Это гарантирует, что глобальные переменные всегда инициализируются в 0 с c99?

Да и нет

static void *g_v_ptr; // initialized to a null pointer 

C99 детализирует значение, но не его представление. «он имеет тип указателя, он инициализируется нулевым указателем» означает, что указатель имеет значение нулевой указатель. Это может быть или не быть NULL. Это может быть или не быть 0. Компилятор может иметь много битовых шаблонов, которые соответствуют нулевому указателю . В любом случае значение g_v_ptr == NULL истинно, а также g_v_ptr == 0, но указатель может иметь другое представление бит, чем 0. Разумеется, шаблон всех нулевых битов обычно легко реализовать и, безусловно, наиболее вероятную реализацию. Тем не менее, спецификация достаточно мягкая, чтобы можно было использовать некоторый ненулевой бит.

Аналогичный случай может быть выполнен для чисел с плавающей запятой.

В любом случае (IAC), то инициализируется значение приравнять 0.