Автоматическая инициализация структуры продолжительности хранения - PullRequest
0 голосов
/ 06 сентября 2018

Возможно, это дубликат, но я прошу прощения за это.
Допустим, у меня есть это struct:

struct foo
{
    int a; 
    int b; 
    int c;
};

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

{
    // other stuff
    struct foo bar;
    // other stuff
}

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

{
    // other stuff
    struct foo bar = {.a = 1}; 
    // other stuff
}

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

{
    // other stuff
    func((struct foo){.a = 1});
    // other stuff
}

Любые ссылки на стандартные C очень ценятся! Спасибо!

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Сводка, TL; DR :

Объяснение срока хранения:

  • Переменная, объявленная внутри функции, имеет автоматическую продолжительность хранения (включая параметры для функций).
  • Переменная, объявленная как static, или переменная, объявленная вне функций в области видимости файла («глобальная»), имеет статическую продолжительность хранения.

Инициализация структуры (и массива):

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

Соответствующая часть стандарта C (C17 6.7.9 §10):

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

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

Где «тип artihmetic» - это стандартная тарабарщина для простых переменных, таких как int, а «совокупность» - стандартная тарабарщина для массивов и структур.

Далее в той же главе (C17 6.7.9 §19):

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


Ответы на ваши вопросы:

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

Нет, это не гарантируется; их значения не определены, как указано в первом предложении цитаты выше.

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

Да, в соответствии с C17 6.7.9 §19, приведенным выше.

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

Да, поскольку составные литералы являются массивами или структурами, они следуют тем же правилам инициализации.

0 голосов
/ 06 сентября 2018

Прежде всего, неинициализированные переменные с автоматическим хранением никогда не будут инициализированы. Из стандарта C11 (ISO / IEC 9899: 2011 § 6.7.9 / 10):

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

Затем из эта ссылка инициализации структуры :

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

И если мы перейдем по «неявной инициализированной» ссылке, мы получим:

объекты со статическим и локальным потоком хранилищем инициализируются следующим образом

  • ...
  • объекты целочисленных типов инициализируются нулем без знака
  • ...

Итак, чтобы ответить на ваши вопросы:

  1. Нет, инициализация не выполняется, поскольку в вашем коде нет явной инициализации (см. Цитату из стандарта)
  2. Да, так как это инициализация структуры
  3. Да, по той же причине, что и 2.

Предоставленные ссылки имеют ссылки на стандарт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...