【问题标题】:Passing NULL for array parameter in C/C++在 C/C++ 中为数组参数传递 NULL
【发布时间】:2011-11-27 03:05:21
【问题描述】:
void DoSomeThing(CHAR parm[])
{

}

int main()
{
    DoSomeThing(NULL);
}

C/C++ 中是否允许为数组参数传递 NULL?

【问题讨论】:

  • @VladLazarenko:我认为你忽略了“可能”和“允许”之间的区别
  • “试试看”是一个很好的第一枪,但尤其是在 C 和 C++ 领域,有数百种编译器特定的语言扩展,想要可移植性的人必须咨询语言律师。并不是说这是一个特别好的问题。
  • @reader:不,这就是我们有规范的原因。仅仅因为它编译并不意味着它是允许的。
  • @JohnDibling -- 仅仅因为它被允许并不意味着它可以编译。
  • @JohnDibling 我认为编译器允许或拒绝事情,规范说明事情应该如何。您无法编译具有规范的程序。如果问题是有效用途,那么我们肯定会查看规范。看看这个帖子:lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-June/… 规范作者更新了规范,因为虽然事情应该按照规范,但在现实世界中并非如此。

标签: c++ c arrays null


【解决方案1】:

首先,您传递给函数的是一个指针,而不是一个数组。用于parm 参数的数组表示法只是CHAR *parm 的语法糖。

所以是的,你可以传递一个NULL 指针。

【讨论】:

    【解决方案2】:

    你不能做的是按值传递一个数组。函数的签名

    void f( char array[] );
    

    转化为:

    void f( char *array );
    

    而且您总是可以将 NULL 作为参数传递给采用指针的函数。

    但是,您可以在 C++ 中通过引用传递数组,在这种情况下,您将无法传递 NULL 指针(或任何其他指针):

    void g( char (&array)[ 10 ] );
    

    请注意,数组的大小是类型的一部分,因此也是签名的一部分,这意味着g 将只接受 10 数组类型的 lvalue-expressions字符

    【讨论】:

      【解决方案3】:

      唯一的问题是如果 DoSomeThing 被重载,在这种情况下编译器可能无法区分调用哪个函数。但从理论上讲,强制转换为适当的类型可以解决这个问题。

      【讨论】:

        【解决方案4】:

        简短的回答是是的,你可以在这种情况下传递NULL(至少对于C,我认为对于C++也是如此)。

        这有两个原因。首先,在函数参数声明的上下文中,声明T a[]T a[N]T *a的同义词; IOW,尽管有数组表示法,a 被声明为指向T指针,而不是T 的数组。来自C语言standard

        6.7.5.3 函数声明符(包括原型)
        ...
        7 将参数声明为“类型的数组”应调整为“限定指针 type'',其中类型限定符(如果有)是在 [] 的 数组类型推导。如果关键字static 也出现在[] 的 数组类型推导,然后对函数的每次调用,对应的值 实际参数应提供对数组的第一个元素的访问,其中至少有 由 size 表达式指定的元素。

        第二个原因是当数组类型的表达式出现在大多数上下文中(例如在函数调用中)时,该表达式的类型被隐式转换(“衰减”)为指针类型,所以实际传递的是什么给函数的是一个指针值,而不是一个数组:

        6.3.2.1 左值、数组和函数指示符
        ...
        3 除非它是sizeof 运算符或一元& 运算符的操作数,或者是 用于初始化数组的字符串字面量,类型为“type”的表达式是 转换为类型为“pointer to type”的表达式,它指向 数组对象并且不是左值。如果数组对象有寄存器存储类,则 行为未定义。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-03-19
          • 2011-12-30
          • 2010-10-20
          • 1970-01-01
          • 2010-10-01
          相关资源
          最近更新 更多