Ответ 1
§5.19/2 (на второй странице он действительно должен быть разделен на многие абзацы) запрещает константные выражения, содержащие
- преобразование lvalue-to-rvalue (4.1), если оно не применяется к
- значение целочисленного или перечисляемого типа, которое относится к энергонезависимому объекту const с предшествующей инициализацией, инициализированным константным выражением или
- значение glvalline типа, которое относится к энергонезависимому объекту, определенному с помощью constexpr, или относится к под-объекту такого объекта
str[1000]
преобразуется в * ( str + 1000 )
, который не относится к подобъекту str
, в отличие от доступа к массиву in-bounds. Таким образом, это диагностическое правило, и компилятор должен жаловаться.
РЕДАКТИРОВАТЬ: Кажется, что есть некоторая путаница в том, как этот диагноз возникает. Компилятор проверяет выражение против §5.19, когда он должен быть постоянным. Если выражение не удовлетворяет требованиям, компилятор должен жаловаться. По сути, требуется проверить постоянные выражения на все, что могло бы в противном случае вызывать поведение undefined. * Это может включать или не включать попытку оценить выражение.
* В С++ 11, "результат, который не определен математически". В С++ 14 "операция, которая имела бы поведение undefined", которая по определению (§1.3.24) игнорирует поведение, которое реализация может определить как резерв.