我可以返回指向VLA的指针吗?

时间:2015-04-11 09:03:54

标签: c arrays pointers language-lawyer c11

这样的函数原型在C中是否有效?

int (*func())[*];

如果是,我该如何定义这些功能?

3 个答案:

答案 0 :(得分:3)

您应该返回一个指向不完整数组类型的指针,而不是*表示可变长度数组只能在参数列表中有效。

示例原型和函数定义:

extern float (*first_row(unsigned, unsigned, float (*)[*][*]))[];

float (*first_row(unsigned n, unsigned m, float (*matrix)[n][m]))[]
{
    return *matrix;
}

您可以这样调用它:

unsigned n = 3, m = 4;
float matrix[n][m];
float (*row)[m] = first_row(n, m, &matrix);

请注意,如果具有自动存储持续时间,则返回指向 函数的数组(可变长度或其他)的指针是未定义的行为。这意味着您只能返回指向作为参数传递或动态分配的可变长度数组的指针。

答案 1 :(得分:3)

根据C标准(6.2.1标识符范围)

  
      
  1. ...(函数原型是声明其参数类型的函数声明。)
  2.   

和(6.7.6.2数组声明符)

  
      
  1. ...如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能   用于具有函数原型范围的声明或类型名称;
  2.   

因此,您可能不会像显示的那样指定函数的返回类型。

考虑到1)函数可能没有返回类型的数组,2)可变长度数组具有自动存储持续时间。因此,如果可以返回这样的数组,则该函数具有未定义的行为。请参见6.7.6.2数组声明符:

  

2如果标识符被声明为具有可变修改类型,则为   应为普通标识符(如6.2.3中所定义),否则   链接,并具有块范围或函数原型范围。 如果   标识符声明为具有静态或线程的对象   存储持续时间,它不应具有可变长度数组类型。

我知道解决问题的两种方法。动态分配数组并将poinetr返回到其第一个元素。或者在结构中打包一个数组。在这种情况下,您可以将函数中的整个结构作为右值返回。

答案 2 :(得分:-1)

技术上你可以,但这不是一个好主意。

int * func(size_t s)
{
    int array[s];
    return array;
}

定义后,变量长度数组与常规数组没有区别,因此当您尝试返回时,它会衰减到指针。返回指向局部变量的指针会导致未定义的行为。