Подтвердить что ты не робот

Почему инициализатор, содержащий строковый литерал, действительный для инициализации массива `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".

4b9b3361

Ответ 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 имеет это.