Структура в стеке - поля инициализированы?
Рассмотрим следующий код:
void func()
{
int p;
...
if (p > MAX) {
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
}
}
В этом фрагменте s
находится в стеке. Гарантируется ли, что компилятор инициализирует все поля структуры нулями?
4 ответа
Если переменная (struct
или иным образом) объявляется локальным для функции или содержащей ее области (т. е. имеет автоматическую продолжительность хранения), она никоим образом не инициализируется. Вам нужно явно установить поля в struct
,
Если вы инициализируете хотя бы одно поле структуры, но не все, то остальные поля будут инициализированы так же, как переменные области действия файла (т. Е. Переменные со статической продолжительностью хранения), что означает NULL
для типов указателей и 0 для числовых типов.
Из раздела 6.7.9 стандарта С:
10 Если объект, имеющий автоматическую продолжительность хранения, не инициализируется явно, его значение является неопределенным. Если объект, который имеет статическое или потоковое время хранения, не инициализируется явно, то:
- если он имеет тип указателя, он инициализируется нулевым указателем;
- если он имеет арифметический тип, он инициализируется равным (положительному или без знака) нулю;
- если это агрегат, каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами, и любое заполнение инициализируется нулевыми битами;
- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами, и любое заполнение инициализируется нулевыми битами;
...
21 Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или членов агрегата или меньше символов в строковом литерале, используемом для инициализации массива известного размера, чем элементов в массиве, то остаток от агрегата должны быть инициализированы неявно так же, как объекты, которые имеют статическую продолжительность хранения.
Нет, это совсем наоборот.
поскольку s
является переменной локальной области автоматического хранения (т. е. блок-области), если явно не инициализировано, ее содержимое не определено.
квотирование C11
Глава §6.7.9
Если объект, имеющий автоматическую продолжительность хранения, не инициализируется явно, его значение является неопределенным. [...].
Однако, если вы хотите инициализировать переменную с нуля для агрегатного типа (y), вы можете просто использовать оператор инициализации, например
aggregate-type variable = {0};
который использует следующее свойство из пункта 21 той же главы (выделено мной)
Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или членов агрегата или меньше символов в строковом литерале, используемом для инициализации массива известного размера, чем элементов в массиве, оставшаяся часть агрегата должна инициализироваться неявно так же, как объекты, которые имеют статическую длительность хранения.
Нет, они не будут инициализированы вообще. Значения структуры будут в конечном итоге с мусором в стеке, где размещена структура.
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
Здесь у вас нет статической переменной, у вас есть автоматическая переменная, поэтому нет предварительной инициализации.
С другой стороны, если вы компилируете с оптимизацией, у вас нет гарантии, где компилятор хранит эту переменную, если вы не проверили вывод ассемблера, который не определен языком Си.