As far as I can tell, this code should not compile, according to §5.19 / 3 and §5.19 / 2 in C ++ 14

But it compiles in gcc 4.9.0. See a live example :

#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[af()]{ 0, 1, 2, 3, 4 }; std::cout << b[4] << '\n'; } 

From § 5.19 / 3 we have:

An integral constant expression is an expression of an integral or non-enumerated type of enumeration implicitly converted to prvalue , where the converted expression is an expression of a constant constant . [Note: such expressions can be used as array boundaries (8.3.4, 5.3.4), since the bit field is of length (9.6), as initializers of the enumerator, if the base type is not fixed (7.2) and as alignments (7.6.2 ) -end note]

The expression af() is an integer expression. It seems to me (although I need clarification on this) that this expression can also be converted to prvalue, because it is the value of x. But I think the real problem here is that the expression af() is not a key constant expression, since it satisfies the bullet point (2.1) in 5.19 / 2.

§5.19 / 2:

conditional expression e is an expression of a constant constant, if only the estimate e , following the rules of the abstract machine (1.9), evaluates one of the following expressions:

(2.1) - this (5.1.1), with the exception of the constexpr or constexpr function, which is evaluated as part of e ;

+7
c ++ language-lawyer c ++ 14 constexpr
source share
2 answers

You are right, af() not a constant expression. Arrays of variable length are not allowed by the C ++ standard. However, the GNU compiler supports them as an extension. You can ask the compiler to give you a warning when using non-standard extensions with the -pedantic or with the -pedantic-errors error.

Edit: Apparently, GCC 4.9 added official support for N3639 , a proposal to add variable-length arrays to the C ++ 14 standard. As a result, the proposal was not included in the standard, but GCC 4.9 was released before C ++ 14, so the changes were not reflected. Thus, VLAs are supported by GCC 4.9 specifically in C ++ 14 mode, and the above parameters do not disable them. Please note that C ++ 14 mode is still experimental (even in GCC 5).

+7
source share

The following custom code

 int x = std::rand(); int r[x] = { 1,2,3 }; 

compiles under g ++, and not because g++ mistakenly treats std::rand() as a constant expression, but because by default it implements VLA. Use -pedantic or -Wvla to warn about them, -Werror=vla to turn these warnings into errors.

+2
source share

All Articles