【问题标题】:Is allocating a dynamic array without specifying size well formed code?分配动态数组而不指定大小格式正确的代码?
【发布时间】:2012-04-04 14:53:15
【问题描述】:

下面的简单程序 sn-p 给出了 gcc-4.3.4 的编译错误。

计划:

int main() 
{   
    char *ptr = new char[10];     
    char *ptr1 = new char[];      
    return 0; 
}  

编译错误:

prog.cpp:在函数“int main()”中:
prog.cpp:4:错误:“]”标记之前的预期主表达式
prog.cpp:3:警告:未使用的变量“ptr”
prog.cpp:4:警告:未使用的变量“ptr1”

但是使用 MSVC 可以干净地编译,没有任何诊断消息。

所以我的问题是:
标准是否允许在不指定 size 的情况下调用 new []?或者这是 MSVC 中的错误?
有人可以提供来自标准的参考,最终会说上面的代码示例格式错误或格式正确吗?


我看过了:

5.3.4 新 [expr.new] &
18.4.1.2 数组形式 [lib.new.delete.array]

但找不到任何关于该行为的确凿证据。


编辑:
添加Language Lawyer 标签。
我期待观察到的行为的答案,无论它是否有用,我完全知道它没有用也不推荐。

【问题讨论】:

  • 如果它是合法的,我不明白它的意义......
  • 我看不出它怎么可能是格式良好的代码?编译器会做什么,猜猜大小?这似乎相当困难(如果不是不可能的话)。
  • +1,有趣,等待好的答案。
  • new char[] 是否分配内存?我认为它只创建一个指针

标签: c++ new-operator language-lawyer


【解决方案1】:

这在语法上不正确。

查看syntax新表达式

noptr-new-declarator 必须在方括号之间包含一个表达式,并且一个表达式 中必须有一个标记。

【讨论】:

    【解决方案2】:

    这不是合法的 c++。

    5.3.4 New [expr.new] 显示了在包含以下行的大列表中调用 new 的合法方式:

    noptr-new-declarator:
            [ expression ] attribute-specifier-seqopt
            noptr-new-declarator [ constant-expression ] attribute-specifier-seqopt
    

    稍后它解释了常量表达式可以是什么(在 5.4.3/6 和 5.4.3/7 中):

    noptr-new-declarator 中的每个常量表达式都应该是一个整数常量表达式 (5.19),并计算为严格的正值。


    经过一番思考,接下来的项目应该是相关的:

    8.3.4/1 [dcl.array],这些部分:

    在声明 T D 中,其中 D 具有以下形式

        D1 [ constant-expressionopt ] attribute-specifier-seqopt
    

    且声明T D1中的标识符类型为“derived-declarator-type-list T”,则D的标识符类型为数组类型;

    如果省略常量表达式,则 D 的标识符类型为“derived-declarator-type-list array of unknown bound of T”,不完整的对象类型。

    5.3.4/1 告诉:

    这个类型应该是一个完整的对象类型,而不是抽象类类型或其数组

    由于你省略了数组大小,所以类型不完整,你的程序不是有效的c++。

    【讨论】:

    • 第一行的 怎么样。 用于多维数组。例如x = new char[plop*5 /*expression */][10 /*const-expression*/][100 /* const-expression */]
    • 快速浏览一下,我看不到 是空的,但是?
    • @LokiAstari 这就是为什么我添加了 constant-expression 可以编辑的内容:noptr-new-declarator 中的每个常量表达式都应该是一个整体常量表达式。既然问题中省略了,那么它就不是标准的c++,而是编译器扩展。它不是 UB,因为它可以编译,但它不应该。
    • @VJovic:由于程序违反了语法规则,因此需要进行诊断;不发出诊断的编译器是不合格的。但是,在发出诊断(警告就足够了)之后,符合标准的编译器可以仍然接受它。一旦它被接受,程序的行为是未定义的(因为标准中没有定义它的行为)。
    • @LokiAstari:仅当它是文档化的扩展时。通过发布诊断,编译器已履行其对标准的承诺。 (“定义的实现”意味着实现必须记录行为。)
    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2011-12-04
    相关资源
    最近更新 更多