【问题标题】:Another case of which compiler is right编译器正确的另一种情况
【发布时间】:2013-09-25 12:16:25
【问题描述】:

在我对幸福的无尽追求中,我遇到了这样的事情

auto temp = new int;
delete[0] temp;

在我看来,我就像...... “这不可能!”所以我启动了最特别和最叛逆的雪花编译器来测试它,你瞧,它编译并运行没有任何问题!

然后我在 GCC (4.8.1) 中尝试了它,但它拒绝了它并出现此错误

错误:数字常量前应为“]”

那请问各位战友,哪一个是对的? (当然不是 MSVC(11) ?!)如果你能引用标准,那就太好了。

【问题讨论】:

  • 你对“幸福”的理解很奇怪。
  • delete[0] - 这是我第一次看到。
  • @nijansen:我就是这么奇怪
  • @LuchianGrigore 你来的时间还不够长。当我第一次学习 C++ 时,不必指定删除中的元素数量是一个新特性,所有编译器都允许你以旧方式做事,并指定。 (当然,即使在那时,new[]delete[]从未有任何用处。)

标签: c++ visual-c++ language-lawyer


【解决方案1】:

回到 C++ 的黎明,当您删除一个数组时,您需要指定您分配的数组的大小:

int * x = new int[10];
// ...
delete [10] x;

这导致了很多问题,所以这个要求早就被取消了。到编写第一个 C++ 标准时,正式不再允许这种语法。

尽管如此,为了与使用它的旧代码兼容,许多编译器仍然接受这种语法。对于 MS VC++,这是默认接受的,但如果您要求符合标准 (-Za),您将收到如下错误:

error C2203: delete operator cannot specify bounds for an array

除此之外,您不应该使用new 来分配数组。使用std::vector

【讨论】:

  • 这看起来不错,但我仍然不太清楚你怎么能打电话给delete[0]。大小为零的数组是什么意思?
  • @DarioP:作为一种过渡措施,编译器通常接受括号中的数字,但完全忽略它(我猜这就是 VC++ 在这种情况下所做的)。
  • 是你的最后一段:他没有使用new 来分配一个数组。他将newdelete[] 不匹配。
  • @JamesKanze:是的,我知道他做了什么,但是根据delete[]的使用,我猜他打算分配一个数组。
【解决方案2】:

delete[0] 根据当前标准是非法语法..

另外,当你用new 分配一个对象时,你应该用delete 释放它,new []delete [] 释放它。它们不应该是可互换的。

C++11 §5.3.5 删除

delete-expression 操作符销毁由 new-expression 创建的最派生对象 (1.8) 或数组。

删除表达式:

::opt delete cast-expression

::opt delete [ ] cast-expression

第一种选择是针对非数组对象,第二种是针对数组。操作数应具有指针类型,或具有单个转换函数(12.3.2)到指针类型的类类型。结果类型为void

【讨论】:

    【解决方案3】:

    标准知道两种不同类型的存储释放,单对象形式的存储释放,18.6.1.1/10-19,即

    void operator delete(void * ptr) noexcept;
    void operator delete(void * ptr, std::nothrow_t const &) noexcept;
    

    和数组形式的存储释放,18.6.1.2/9-17,也就是

    void operator delete[](void * ptr) noexcept;
    void operator delete[](void * ptr, std::nothrow_t const &) noexcept;
    

    但是,历史上(标准前)有一个 delete[N] 释放器,它要求您释放为数组分配的数量。我怀疑这就是您的编译器正在解释的内容。

    【讨论】:

      【解决方案4】:

      它运行没有问题,因为你很幸运。通常用 new 分配和用 delete[] 删除是未定义的行为,“运行没有任何问题”属于 UB 允许的行为集。像这样的代码有时在测试中运行良好,但在最意想不到的时刻中断,例如为您最重要的客户提供现场演示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-12
        • 2019-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-09
        相关资源
        最近更新 更多