42

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?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740

2 Answers2

45

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.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 20
    I am dubious about the usefulness of allowing `double` to be used as the size of an array... it seems more likely to let bugs pass silently than anything else :( – Matthieu M. Dec 12 '18 at 15:48
  • 13
    @MatthieuM. I agree, I believe it is a defect and that the intent was really to say `contextually implicitly converted`. I am filing a defect report on this hopefully today but who knows maybe I am wrong :-( – Shafik Yaghmour Dec 12 '18 at 15:57
  • 3
    @MatthieuM. FYI I filed a defect report, processing takes a while so I don't expect to have an update anytime soon though. – Shafik Yaghmour Dec 14 '18 at 17:56
1

From to (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.

Bakudan
  • 19,134
  • 9
  • 53
  • 73
gsamaras
  • 71,951
  • 46
  • 188
  • 305