Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++14 is it valid to use a double in the dimension of a new expression?

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?

like image 544
Shafik Yaghmour Avatar asked Dec 12 '18 14:12

Shafik Yaghmour


2 Answers

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 to std::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.

like image 97
Shafik Yaghmour Avatar answered Nov 19 '22 02:11

Shafik Yaghmour


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 to std::size_t. [..]

with only this part ([expr.const]) missing from the C++17 draft.

like image 27
gsamaras Avatar answered Nov 19 '22 03:11

gsamaras