§5.19/2 (on the second page; it really should be split into many paragraphs) forbids constant expressions containing
— an lvalue-to-rvalue conversion (4.1) unless it is applied to
— a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression, or
— a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object
str[1000]
translates to * ( str + 1000 )
, which does not refer to a subobject of str
, in contrast with an in-bounds array access. So this is a diagnosable rule, and the compiler is required to complain.
EDIT: It seems there's some confusion about how this diagnosis comes about. The compiler checks an expression against §5.19 when it needs to be constant. If the expression doesn't satisfy the requirements, the compiler is required to complain. In effect, it is required to validate constant expressions against anything that might otherwise cause undefined behavior.* This may or may not involve attempting to evaluate the expression.
?* In C++11, "a result that is not mathematically defined." In C++14, "an operation that would have undefined behavior," which by definition (§1.3.24) ignores behavior that the implementation might define as a fallback.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…