Краткий обзор
C99 и более поздние версии гарантируют, что оставшиеся символы будут обнулены. C89 / C90 / C95 не дает этой гарантии и не указывает значения оставшихся символов. Вероятно, это был непреднамеренный недосмотр, и я предполагаю, что большинство или все компиляторы до C99 в любом случае инициализировали бы оставшиеся символы нулем. Если вы используете компилятор C99 или более поздней версии, инициализация с нуля гарантирована.
Подробные сведения
char test[5]="";
Из-за дефекта в стандарте C89 / C90 это было только гарантированно инициализировать test[0]
до '\0'
. Остальные элементы test
были оставлены неуказанными.
Поправка C95 не решает эту проблему.
Стандарт C99 исправил дефект, требуя инициализации test
для всех нулей.
Другой пример:
char foo[5] = "foo";
В C89 / C90, C95 язык гарантировал foo[0]=='f', foo[1]=='o', foo[2]=='o', foo[3]=='\0'
, но ничего не говорил о значении foo[4]
. В C99 и более поздних версиях он гарантированно инициализируется, как если бы вы написали:
char foo[5] = { 'f', 'o', 'o', '\0' };
, что во всех выпусках стандарта C гарантирует foo[4]=='\0'
.
Цитирования
Стандарт ANSI C 1989 года и стандарт ISO C 1990 года эквивалентны, отличаются только ненормативным вводным материалом и перенумерацией разделов. Поправка 1995 года обновила стандарт, но не повлияла на инициализацию массива.
Стандарт ISO C 1990 года, раздел 6.5.7, гласит:
Массив типа символов может быть инициализируется литералом строки символов, необязательно заключенным в фигурные скобки. Последовательные символы литерала символьной строки (включая завершающий нулевой символ, если есть место или массив имеет неизвестный размер) инициализируют элементы массива.
и более поздние в том же разделе:
Если в заключенном в скобки списке меньше инициализаторов, чем членов агрегата, оставшаяся часть агрегата должна быть инициализирована неявно так же, как объекты, у которых есть c срок хранения.
В нем указано, что конечные элементы инициализируются нулем для заключенного в скобки списка, но не делает того же оператора для строкового литерального инициализатора. (Я предполагаю, что это был непреднамеренный недосмотр, и что большинство компиляторов в любом случае заполнили бы оставшиеся элементы нулем, поскольку в некоторых случаях они уже должны были это делать.)
Каждое издание стандарта C имеет набор связанных с ним отчетов о дефектах:
Отчет о дефектах C90 # 060 , представленный в 1993 году П. Дж. Плаугером и / или Ларри Джонсом, поднял эту проблему:
Когда массив char
(или wchar_t
) инициализируется строковым литералом, который содержит меньше символов, чем массив, инициализируются остальные элементы массива ?
Подпункт 6.5.7 Инициализация , стр. 72, только говорит (выделено мое):
Если в скобках * 1081 меньше инициализаторов * список, чем есть агрегированные члены, остальная часть аггр egate должен быть неявно инициализирован так же, как и объекты, которые имеют c длительность хранения.
Ответ на этот отчет о дефектах привел к пересмотренной формулировке в стандарте C99, раздел 6.7.8. пункт 21 (выделение выделено):
Если в заключенном в скобки списке меньше инициализаторов, чем элементов или элементов агрегата, или меньше символов в строковом литерале, используемом для инициализации массив известного размера, чем есть элементы в массиве , остальная часть агрегата должна быть инициализирована неявно так же, как объекты, которые имеют c продолжительность хранения.