42

在 C++14 中给出以下代码:

void foo() {
  double d = 5.0;
  auto p1 = new int[d];
}

clang 在没有诊断的情况下编译它,而另一方面 gcc 产生以下诊断(在 Godbolt 中查看它):

error: expression in new-declarator must have integral or enumeration type
    7 |     auto p1 = new int[d];
      |                       ^

我特别标记了这个 C++14,因为在 C++11 模式下,clang 将其视为格式错误并产生以下诊断信息(在 godbolt 中查看它):

error: array size expression must have integral or unscoped enumeration type, not 'double'
    auto p1 = new int[d];
              ^       ~

铿锵正确吗?如果是这样,C++14 中发生了什么变化以允许这样做?

4

2 回答 2

44

Clang 是正确的,[expr.new]p6中的关键措辞与 C++11 草案中的以下内容不同:

noptr-new-declarator中的每个常量表达式都应是一个整数常量表达式 ([expr.const]) 并计算为严格的正值。noptr-new-declarator中的表达式应为整数类型、无作用域枚举类型或存在单个非显式转换函数到整数或无作用域枚举类型的类类型([class.conv])。如果表达式是类类型,则通过调用该转换函数来转换表达式,并使用转换结果代替原始表达式。…</p>

在 C++14 草案中对此:

noptr-new-declarator中的每个常量表达式都应为类型转换的常量表达式 ([expr.const]),并应计算为严格的正值。noptr-new-declarator中的表达式被隐式转换为. …</p> std::size_tstd::size_t

在 C++14 中,对noptr-new-declarator中的表达式的要求被削弱为不需要整数、无范围枚举或具有单个非显式转换函数的类到这些类型之一,而只允许隐式转换到size_t .

措辞的变化来自提案A Proposal to Tweak certain C++ Contextual Conversions, v3

于 2018-12-12T14:25:33.737 回答
1

(对于像我一样想知道的人),措辞几乎保持不变(不像 @ShafikYaghmour 回答的从 C++11 到 C++14),如本C+中所述+17 选秀

noptr-new-declarator中的每个常量表达式都应是类型转换的常量表达式,并应计算为严格的正值。noptr-new-declarator中的表达式被隐式转换为. [..]std::size_tstd::size_t

([expr.const])C++17 草案中仅缺少这一部分。

于 2018-12-14T14:34:47.870 回答