int main(void)
{
char four[4] = "four";
return 0;
}
При компиляции как программы на C ++, G ++ сообщает
xxx.cpp: в функции int main ():
xxx.cpp: 3: ошибка: строка инициализатора для массива символов слишком длинная
При компиляции программы на Си, GCC сообщает об отсутствии ошибок
Мне кажется, что назначение правильно копирует все 4 байта в переменную, как я и ожидал.
Так что мой вопрос сводится к .....
Правильно ли наблюдаемое поведение в C или я где-то касаюсь неопределенного поведения, или это вообще что-то еще?
Краткий ответ: ваш код действителен на C, но недействителен C ++.
Длинный ответ:
«четыре»
на самом деле состоит из 5 символов - там для вас добавлено \ 0
. В разделе 6.7.8 Инициализация , параграф 13, стандарт C говорит:
Массив символьного типа может быть инициализирован литералом символьной строки, необязательно заключенным в фигурные скобки. Последовательные символы литерала символьной строки (включая завершающий нулевой символ, если есть место или если размер массива неизвестен) инициализируют элементы массива.
Таким образом, \ 0
просто игнорируется в вашей программе, когда она компилируется на C. C ++ обрабатывает ее по-другому. Фактически, этот конкретный случай вызывается явно в спецификации C ++ (Раздел 8.5.2 Символьные массивы , параграф 2):
Инициализаторов не должно быть больше, чем есть элементы массива. [ Пример:
char cv [4] = "asdf"; // ошибка
неправильно сформирован, поскольку нет места для подразумеваемого завершающего
’\ 0’
. - конечный пример ]
Строка "четыре" на самом деле содержит пять байт: четыре буквы плюс нулевой байт (\0) в качестве терминатора строки. Я давно не писал на C или C++, но я бы предположил, что компилятор C по какой-то причине молча игнорирует это.
То, что вы видите, это разница между C и C++. Си позволяет вам иметь дополнительные инициализаторы, которые игнорируются. C++ запрещает это - если вы указываете размер строки (или массива), он должен быть достаточно большим, чтобы вместить все инициализаторы (включая терминатор NUL, в случае со строкой), иначе код будет неверно сформирован (стандартное выражение "это недопустимо - ожидайте, что компилятор отвергнет это").