Что является основным константным выражением в стандарте C ++ 11?

Есть 11 ссылок на выражение core constant expression в последнем проекте стандарта C ++ 11 (N3690), и ни один из них не определяет, что это за сущность.

Также можно обнаружить, что выражение core constant expression довольно хорошо определен Вот , в основном в тех же терминах, которые стандарт использует для определения выражения conditional-expression,

Поэтому я хотел бы получить некоторую информацию по этому вопросу, которая, на мой взгляд, неверна в Стандарте.

Теперь, принимая определение в cppreference правильно, я также хотел бы знать, почему следующий фрагмент компилируется в Coliru И в Ideone, несмотря на пункт (10) в намеченном определении?

#include <iostream>

int main()
{
const double x = 2.;
constexpr double y = x;
std::cout << y << std::endl;
}

Я специально думаю с точки зрения lvalue to rvalue implicit conversion переменной x в выражении constexpr double y = x;, который не охватывается ни одним из пунктов (a), (b) и (c) в пункте (10), упомянутом выше.

Спасибо за помощь.

4

Решение

N3690 делает определим термин «основное константное выражение» в 5.19p2 [expr.const]:

условно-выражение е это выражение основной константы если только
оценка е, следуя правилам абстрактной машины (1.9),
оценил бы одно из следующих выражений:

[список опущен]

Опубликованный стандарт ISO C ++ 2011 определяет его в том же разделе.

Что касается того, действительно ли это определение, см. Также раздел 1.3, пункт 3:

Термины, которые используются только в небольшой части этого международного
Стандарт определяется, где они используются, и курсивом, где они находятся.
определены.

Стандарт также использует курсив для синтаксических категорий, таких как условно-выражение, но «выражение основной константы» — это определенный термин, а не синтаксическая категория (это неуловимо, но вы можете сказать, используя пробелы, а не дефисы для разделения слов).

Что касается примера кода:

const double x = 2.;
constexpr double y = x;

мое чтение стандарта заключается в том, что это неверно, потому что x является не выражение основной константы. Это будет действительно, если x а также y имели целочисленный тип или тип перечисления, но для плавающей запятой такого разрешения нет. Преобразование lvalue-в-значение (преобразование имени объекта x к его стоимости 2.0) не допускается в выражение основной константы если только он не соответствует одному из трех перечисленных критериев (см. C11 5.19, 9-я пуля, три подпункта).

Это подразумевает, что компиляторы, которые принимают приведенный выше код без диагностики, являются несоответствующими (т.е. содержат ошибки). (Если я что-то упустил, что вполне возможно.)

Что подразумевает, что http://en.cppreference.com/w/cpp/language/constant_expression неправильно. В нем говорится, что выражение ядра с константой может содержать преобразование из lvalue в rvalue значения lvalue, которое «имеет литеральный тип и относится к объекту, определенному с помощью постоянного выражения (или его подобъекта)». Фактический стандарт имеет более строгие требования: объект должен быть определен с constexpr, (Возможно, cppreference.com был основан на более раннем проекте?)

Таким образом, пример кода можно сделать действительным, изменив его на:

constexpr double x = 2.;
constexpr double y = x;
5

Другие решения

Других решений пока нет …