Но он компилируется в gcc 4.9.0. См live example:Насколько я могу судить, этот код не должен компилироваться, согласно §5.19/3 и §5.19/2 в C++ 14
#include <iostream>
struct A {
constexpr A(): i(5) {}
int&& f() { return std::move(i); }
int i;
} a;
A&& f(A& a) { return std::move(a); }
int main() {
A a;
int b[a.f()]{ 0, 1, 2, 3, 4 };
std::cout << b[4] << '\n';
}
От §5.19/3 имеет:
Неотъемлемой константой является выражение интеграла или незаданного перечислимого типа, неявно преобразуется в prvalue, где преобразованные выражение представляет собой основное константное выражение. [Примечание: такие выражения могут использоваться в качестве границ массива (8.3.4, 5.3.4) в качестве битового поля длин (9.6) в качестве инициализаторов перечислителя, если базовый тип не является фиксированным (7.2), а в качестве выравниваний (7.6.2). Примечание]
Выражение a.f()
является выражением целочисленного типа. Мне кажется (хотя мне нужно разъяснение по этому вопросу), что это выражение также можно преобразовать в prvalue, потому что это значение x. Но я думаю, что настоящая проблема здесь заключается в том, что выражение a.f()
равно не выражение константы ядра, так как оно удовлетворяет точке пули (2.1) в п. 5.19/2.
§5.19/2:
Условное выражение
e
является одним из основных константа если только оценкиe
, следуя правилам абстрактной машины (1.9), бы оценить одно из следующих действий выражения:(2.1) -
this
(5.1.1), за исключением вconstexpr
функции или конструктора в constexpr, который оценивается как частьe
;
Если вы попробуете скомпилировать это с помощью clang ++, он указывает, что «массивы переменных размеров не разрешены» - поэтому у меня такое чувство, что gcc просто недостаточно педантичен. –
Убедительный GCC для обеспечения соответствия может быть болью. Я обнаружил, что компиляция с флагом '--pedantic-errors', похоже, делает трюк. Я бы предпочел строгое соответствие по умолчанию и флаги, чтобы отключить его. – Galik
Включает ли этот сайт режим строгой совместимости в компиляторе (я слишком ленив, чтобы выяснить, какие сценарии/сторонние сайты позволяют увидеть его для себя)? В противном случае причина в том, что g ++ имеет нестандартное расширение для массивов продолжительности хранения с не постоянным размером. – celtschk