Инициализация списком ссылки на массив неизвестного размера: должен ли он выводить размер массива? - PullRequest
5 голосов
/ 06 апреля 2019

Следующий код прекрасно компилируется в Clang и выводит размер int [3] array

#include <iostream>

int main()
{
  const int (&a)[] = { 1, 2, 3 };
  std::cout << sizeof a << std::endl;
}

Однако в GCC объявление компилируется нормально, а sizeof a нет: очевидно, GCC отказывается "выводить""размер массива и заканчивается a в качестве ссылки на тип const int [], который является неполным.

Что такое предполагаемое поведение при таких инициализациях?

9.3.4/3 , по-видимому, является соответствующей частью стандарта для таких случаев, но сам по себе он, похоже, не дает окончательного ответа.

1 Ответ

1 голос
/ 06 апреля 2019

Стандарт не совсем ясен в этом вопросе, и я думаю, что интерпретация GCC, вероятно, будет такой, как задумал WG21, но я не уверен.

Соответствующим разделом стандарта является [dcl.array], который описывает, как определить тип, объявленный объявлением, в котором декларатор содержит оператор формирования массива []. Я цитирую соответствующую часть:

Граница массива также может быть опущена, когда за декларатором следует инициализатор (11.6) или когда за декларатором статического члена данных следует фигурная скобка или равный инициализатор (12,2). В обоих случаях граница рассчитывается из числа предоставленных начальных элементов (скажем, N) (11.6.1), а тип идентификатора D является «массивом N T».

Не совсем так, относится ли это только к объявлению самого массива, или же оно должно применяться в случае ссылки на массив, поскольку при интерпретации [dcl.ref] необходимо обращаться к [dcl.array] ] (который описывает операторы & и &&). Тем не менее, я думаю, что последняя интерпретация должна быть отклонена, так как мы не ожидаем, что инициализатор приведет к выводу границы, когда [] скрыт в деклараторе. Для примера рассмотрим надуманный пример:

int (*a[1])(const int (&)[]) = {0};

Здесь GCC и Clang согласны , и я думаю, что здравый смысл также согласен с тем, что тип a равен int (*[1])(const int (&)[]), а не int (*[1])(const int (&)[1]): тот факт, что a обладает инициализатором не вызывает вывод внутренней привязки массива.

Исходя из этого, я бы сказал, что GCC правильно не выводит массив, связанный с вашим кодом, так что a имеет тип const int (&)[].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...