Почему инициализатор, содержащий строковый литерал, действительный для инициализации массива `char '?
Оказывается, что char c[] = {"a"};
полностью действует как в С++ 03, так и С++ 11.
Я бы не ожидал, что это будет, потому что это массив char
not of char const*
, и я ожидал бы, что инициатор скобки потребует совместимый тип для каждого из своих "элементов". Он имеет один элемент и a char const*
не a char
.
Итак, что делает эту инициализацию действительной? И есть ли обоснование для этого?
Аналогично, char c[] = {"aa"};
компилируется, а печать c
приводит к выводу "aa
".
Я бы ожидал, что char c[]{"a"}
будет действительным в С++ 11, конечно, но это не то же самое! Аналогично, char c[] = {'a'}
очевидно в обоих, как и char c[] = "a"
.
Ответы
Ответ 1
Скалярные типы также могут быть инициализированы с помощью фигурных скобок (как и структур и массивов).
struct S { int x, char c };
S s = {5, 'a'};
int arr[] = {5, 6, 7};
/* (my guess) out of consistency */
int z = { 4 };
И поскольку строковые литералы могут быть назначены массиву char и указателям
char arr[] = "literal";
char* ptr = "another";
Кажется уместным разрешить char arr[] = { "literal" };
.
Ответ 2
Хотя это может и не быть интуитивно понятным, это просто разрешено; существует четкое правило для него в обоих стандартах:
[2003: 8.5.2/1]:
A char
массив (будь то простой char
, signed char
или unsigned char
) может быть инициализирован строковым литералом (необязательно заключенные в фигурные скобки); массив a wchar_t
может быть инициализирован широким string-literal (необязательно заключен в фигурные скобки); последовательные символы строки-literal инициализируют элементы массива. [..]
[n3290: 8.5.2/1]:
массив char (будь то plain char
, signed char
или unsigned char
), массив char16_t
, массив char32_t
или wchar_t
массив может инициализироваться символом узкого символа, char16_t
строковым литералом, char32_t
строковый литерал или широкий строковый литерал соответственно или соответствующий строковый литерал, заключенный в фигурные скобки. последовательный символы значения строкового литерала инициализируют элементы массива.
Я не могу объяснить, почему комитет сделал это таким образом.
Ответ 3
Я предполагаю, что для совместимости с C? Фактически, T x = { value of T };
применяется и к другим типам T. В стандарте C99
6.7.8/11: Инициализатор для скаляра должен быть единственным выражением , необязательно заключенным в фигурные скобки.
6.7.8/14: массив символьного типа может быть инициализирован символьным строковым литералом, , необязательно заключенным в фигурные скобки.
6.7.8/15: массив с типом элемента, совместимым с wchar_t
, может быть инициализирован широким строковым литералом, , возможно, заключенным в фигурные скобки.
Я не знаю, почему C имеет это.