int * array = new int [size]() 的有效性问题

5
int * array = new int [size]();

operator()允许将数组的所有值设置为0(所有位都是0),这被称为值初始化。

从哪个版本的g++开始有效?

其他编译器呢?

在标准中我可以在哪里找到它?


1
这是C语言中的语法错误。您是否意味着要在那里使用C标签? - pmg
3
这让我想起为什么我讨厌C++。 奇怪的语法,秘密握手,专有扩展... 这是一门只有母亲会喜欢的语言! - Carl Smotricz
可能是重复问题:https://dev59.com/9nI-5IYBdhLWcg3w-9yb - Kirill V. Lyadvinsky
5
@carl:说到奇怪的语法,C++ 增加了很少的内容。只需想想现成的 strcpy 实现 while(*p1++=*p2++); - 那种晦涩的运算符拼接令每个新手都感到震惊。(不用争论,后缀自增和解引用对新手程序员来说确实是晦涩的。)在上面的例子中,没有“秘密握手”,也没有专有扩展。它所做的就是允许更安全地分配一个整数数组的版本,同时仍然允许用户使用不太安全但略微更快的版本。这是由 ISO 标准确定的。 - sbi
3个回答

6
这是C++标准的一部分; 如果在g++中无效,则g++不符合标准。从C++标准(ISO / IEC 14882:2003)中,有几个相关章节:
新表达式中5.3.4/15所述:
如果new-initializer的形式为(),则该项将进行值初始化
初始化程序中8.5/5所述:
对于类型为T的对象进行值初始化意味着:
- 如果T是具有用户声明构造函数(12.1)的类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是非法的); - 如果T是没有用户声明构造函数的非联合类类型,则对T的每个非静态数据成员和基类组件进行值初始化; - 如果T是数组类型,则每个元素都进行值初始化; - 否则,对象将被零初始化。
因此,对于int数组,这是一个标量类型,适用第三和第四个要点。

谢谢!从哪个版本的g++开始有效? - Nadir SOUALEM

1

()初始化(包括您的示例)始终是标准C++的一部分,自C++98以来就存在。尽管在较新版本的标准中有一些更改,但它们不适用于您的示例。

GCC编译器在2.x.x系列的版本中已知会错误处理()初始化程序。MSVC++编译器在VC6中已知会错误处理()初始化程序。较新版本的MSVC++根据C++98规范处理()初始化程序。


你有源代码吗?对于g++ 3.4.3似乎会失败。 - Nadir SOUALEM
嗯...在我的3.4.4版本中运行良好。它在3.4.3版本中具体是怎么失败的?数组里有垃圾数据吗?还是拒绝编译? - AnT stands with Russia
抱歉,它是gcc 3.4.6 20060404(Red Hat 3.4.6-9)。它可以编译成功,当我检查元素array [0],array [1]等时,它们都不为零!!! - Nadir SOUALEM
我对此没有解释。再次说明,在我的3.4.4中它运行良好。你确定在实验中没有忘记()这一部分吗? - AnT stands with Russia

0

这是来自于2009-11-09的“C++编程语言标准工作草案”:

8.5 初始化
...
7 对于类型为T的对象进行值初始化意味着:

  • 如果T是一个(可能带有cv限定符的)类类型(第9条款),并且具有用户提供的构造函数(12.1),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化无效);
  • 如果T是一个(可能带有cv限定符的)非联合类类型,没有用户提供的构造函数,则该对象被零初始化,并且如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
  • 如果T是一个数组类型,则每个元素都进行值初始化;
  • 否则,该对象被零初始化。

...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接