C и C ++: частичная инициализация автоматической структуры

Например, еслиsomestruct имеет три целочисленных члена, я всегда думал, что это нормально делать в функции C (или C ++):

somestruct s = {123,};

Первый элемент будет инициализирован 123, а последние два - 0. Я часто делаю то же самое с автоматическими массивами:int arr[100] = {0,}; так что все целые числа в массиве инициализируются в ноль.


Недавно я прочитал вGNU C Справочное руководство тот:

If you do not initialize a structure variable, the effect depends on whether it is has static storage (see Storage Class Specifiers) or not. If it is, members with integral types are initialized with 0 and pointer members are initialized to NULL; otherwise, the value of the structure's members is indeterminate.


Может кто-нибудь сказать мне, что говорят стандарты C и C ++ относительно частичной автоматической структуры и автоматической инициализации массива? Я делаю приведенный выше код в Visual Studio без проблем, но я хочу быть совместимым с gcc / g ++ и, возможно, другими компиляторами. Спасибо

 Björn Pollex31 мая 2012 г., 08:32
Для C ++ - часть вопроса,this question может вас заинтересовать

Ответы на вопрос(4)

// You can use something like this:
typedef struct {

    ...;

    ...;

} somestruct;

// Declaration of struct
somestruct st;

// Initialising with 0. It does not depend on the size of the
// structure and the number of elements in it.
// memset() initialisation doesn't care if struct is static or dynamic.
// but don't forget to use st instead &st to dynamic.
memset(&st, 0, sizeof(somestruct));

новейшие версии gcc также позволяют «частично» инициализировать и обнулить одновременно:

typedef struct{
  int a,b,c;
}T;

T s = {0, .b=5};

члены структуры теперь будут иметь следующие значения:a=0, b=5, c=0

У меня нет никакой информации о том, позволяют ли это другие компиляторы: p

 26 февр. 2013 г., 20:55
Это особенность C99, не особенно новая. Это называется "назначенным инициализатором". и широко поддерживается. Однако это не функция C ++. C ++ использует конструкторы.
Решение Вопроса

Связанная документация gcc не говорит оPartial Initialization это просто говорит о(Complete)Initialization или жеNo Initialization.

What is partial Initialization?

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

Пример:

int array[10] = {1,2};                    //Case 1:Partial Initialization

What is (Complete)Initialization or No Initialization?

Инициализация означает предоставление некоторого начального значения создаваемой переменной в то же время, когда она создается. т.е. в том же коде оператора.

Пример:

int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initialization
int array[10];                            //Case 3:No Initialization

Цитируемый абзац описывает поведениеCase 3.

Правила, касающиеся частичной инициализации (Case 1) хорошо определены стандартом, и эти правила не зависят от типа хранения инициализируемой переменной.
AFAIK, Все основные компиляторы имеют 100% соответствие этим правилам.

Can someone please tell me what the C and C++ standards say regarding partial automatic structure and automatic array initialization?

Стандарты C и C ++ гарантируют, что даже если целочисленный массив находится в автоматическом хранилище и если в списке, заключенном в скобки, меньше инициализаторов, то неинициализированные элементыmust быть инициализирован в0.

C99 Standard 6.7.8.21

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

В C ++ правила изложены с небольшой разницей.

C++03 Standard 8.5.1 Aggregates
Para 7:

If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5). [Example:

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is,0. ]

Хотя инициализация значения определяется в
C++03 8.5 Initializers
Para 5:

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

 loop01 июн. 2012 г., 02:57
Спасибо за этот подробный ответ. Что касается инициализации значения, знаете ли вы, что в C ++ выражение вида DWORD () гарантированно равно 0? Bjérn прокомментировал мой вопрос и связал вопрос, касающийся инициализации значения, но мне неясно, поддерживает ли Visual Studio это, потому что это C ++ 98, а не C ++ 03.
 25 авг. 2017 г., 19:48
@Mecki: Хороший вопрос. Это было слишком упрощенное обобщение в ответе.
 loop01 июн. 2012 г., 05:08
Хорошо спасибо еще раз
 25 авг. 2017 г., 17:40
then the uninitialized elements must be initialized to 0. ммм ... нет Они не инициализируются нулем, аinitialized implicitly the same as objects that have static storage duration, который может быть равен нулю и в настоящее время, вероятно, равен нулю для всех стандартных типов языка Си, но стандарт явно не требует нуля. Извините за придирки, но это немного странно, если вы говорите что-то, а затем цитируете стандарт, который говорит что-то другое (даже если вы, вероятно, оба правы в том, что говорите).
 01 июн. 2012 г., 05:04
@test: AFAIK, в C ++ 98 было только два типа инициализации,Zero Initialization & Амп;Default Initialization, C ++ 03 добавленоValue Initialization, DWORD() в C ++ 98 будет оцениваться какZero Initialization.

В C объектыnever частично инициализирован - если какая-либо часть из них инициализирована, весь объект (и все подобъекты рекурсивно) инициализируются. Если явный инициализатор не предоставлен, то элементы инициализируются как «ноль соответствующего типа».

Цитата в вашем вопросе относится к тому моменту, когда инициализатор для всего объекта полностью исключен, а не к тому моменту, когда у субобъекта отсутствует инициализатор. Например, предполагая, чтоarr имеет автоматическое время хранения, то это:

int arr[100] = { 123 };

инициализируетсяarr[0] в123 и любой другой элементarr в0, Тогда как это:

int arr[100];

оставляет каждый элементarr неинициализированный. Это последний случай, на который ссылается цитата.

 14 июл. 2018 г., 14:30
В этом случае int arr [100] = {123}; , все остальные оставшиеся элементы массива arr инициализированы в ASCII 0 или числовой 0?
 16 июл. 2018 г., 03:08
Есть ли способ проверить это, чтобы подтвердить, что это не ASCII 0, потому что, хотя я делаю% c, он ничего не печатает, поэтому я хочу знать, как подтвердить, заполняет ли компилятор оставшиеся записи нулевым (ASCII 0) или числовым 0?
 20 июл. 2018 г., 05:47
@RadhaGogia: числовой / целое число нольis нулевой символ ASCII при печати с использованием%c.
 14 июл. 2018 г., 16:09
@RadhaGogia: числовой 0.

Ваш ответ на вопрос