В С++ 14 допустимо ли использовать double в измерении нового выражения? - программирование

В С++ 14 допустимо ли использовать double в измерении нового выражения?

В С++ 14 дан следующий код:

void foo() {
  double d = 5.0;
  auto p1 = new int[d];
}

clang компилирует это без диагностики, в то время как gcc, с другой стороны, выдает следующую диагностику (см. это в Godbolt):

error: expression in new-declarator must have integral or enumeration type
    7 |     auto p1 = new int[d];
      |                       ^

Я специально обозначил этот С++ 14, потому что в режиме С++ 11 clang рассматривает это как плохо сформированное и производит следующую диагностику (см. Это в прямом эфире):

error: array size expression must have integral or unscoped enumeration type, not 'double'
    auto p1 = new int[d];
              ^       ~

Является ли лязг правильно? Если так, что изменилось в С++ 14, чтобы это разрешить?

4b9b3361

Ответ 1

Clang верен, ключевая формулировка в [expr.new] p6 отличается от следующей в черновике C++ 11:

Каждое константное выражение в деклараторе noptr-new должно быть целочисленным константным выражением ([expr.const]) и иметь строго положительное значение. Выражение в noptr-new-объявителе должно иметь целочисленный тип, тип перечисления с незаданной областью или тип класса, для которого существует единственная неявная функция преобразования в тип перечисления с целой или незаданной областью ([class.conv]). Если выражение имеет тип класса, выражение конвертируется путем вызова этой функции преобразования, и результат преобразования используется вместо исходного выражения....

на это в проекте C++ 14:

Каждое константное выражение в объявителе noptr-new должно быть преобразованным константным выражением ([expr.const]) типа std::size_t и должно принимать строго положительное значение. Выражение в деклараторе noptr-new неявно преобразуется в std::size_t...

В C++ 14 требование для выражения в noptr-new-деклараторе было ослаблено, чтобы не требовать целочисленного перечисления с незаданной областью или класса с единственной неявной функцией преобразования для одного из этих типов, а просто разрешать неявные преобразования в size_t,

Изменения в формулировке произошли от предложения A Tweak Certain C++ Contextual Conversions, v3.

Ответ 2

От до (для тех, кто интересуется, как я), фраза остается практически такой же (в отличие от С++ 11 до С++ 14, как ответил @ShafikYaghmour), как указано в этом С++ 17 черновик:

Каждое константное выражение в деклараторе noptr-new должно быть преобразованным константным выражением типа std::size_t и должно принимать строго положительное значение. Выражение в деклараторе noptr-new неявно преобразуется в std::size_t. [..]

только эта часть ([expr.const]) отсутствует в проекте С++ 17.