In C++14 given the following code:
void foo() {
double d = 5.0;
auto p1 = new int[d];
}
clang compiles this without diagnostic while gcc on the other hand produces the following diagnostic (see it live in godbolt):
error: expression in new-declarator must have integral or enumeration type
7 | auto p1 = new int[d];
| ^
I specifically labeled this C++14 because in C++11 mode clang treats this as ill-formed and produces the following diagnostic (see it live in godbolt):
error: array size expression must have integral or unscoped enumeration type, not 'double'
auto p1 = new int[d];
^ ~
Is clang correct? If so what changed in C++14 to allow this?
Clang is correct, the key wording in [expr.new]p6 changes from the following in the C++11 draft:
Every constant-expression in a noptr-new-declarator shall be an integral constant expression ([expr.const]) and evaluate to a strictly positive value. The expression in a noptr-new-declarator shall be of integral type, unscoped enumeration type, or a class type for which a single non-explicit conversion function to integral or unscoped enumeration type exists ([class.conv]). If the expression is of class type, the expression is converted by calling that conversion function, and the result of the conversion is used in place of the original expression. …
to this in the C++14 draft:
Every constant-expression in a noptr-new-declarator shall be a converted constant expression ([expr.const]) of type
std::size_t
and shall evaluate to a strictly positive value. The expression in a noptr-new-declarator is implicitly converted tostd::size_t
. …
In C++14 the requirement for the expression in a noptr-new-declarator was weakened to not require an integral, unscoped enumeration or a class with a single non-explicit conversion function to one of those types but just allow implicit conversions to size_t.
The change in wording came from the proposal A Proposal to Tweak Certain C++ Contextual Conversions, v3.
From c++14 to c++17 (for the ones that wonder like me), the phrasing remains practically the same (unlike from C++11 to C++14 as @ShafikYaghmour answered), as stated in this C++17 draft:
Every constant-expression in a noptr-new-declarator shall be a converted constant expression of type
std::size_t
and shall evaluate to a strictly positive value. The expression in a noptr-new-declarator is implicitly converted tostd::size_t
. [..]
with only this part ([expr.const])
missing from the C++17 draft.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With