我可以 return 指向 VLA 的指针吗?
Can I return pointer to VLA?
这样的函数原型在 C 中有效吗?
int (*func())[*];
如果是,我该如何定义这些函数?
技术上可以,但这不是一个好主意。
int * func(size_t s)
{
int array[s];
return array;
}
定义可变长度数组后,它与常规数组没有什么不同,因此当您尝试 return 它时,它会衰减为指针。返回指向局部变量的指针会导致未定义的行为。
您应该 return 指向不完整数组类型的指针,因为 *
可变长度数组的表示法仅在参数列表中有效。
示例原型和函数定义:
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);
请注意,return指向已在函数中声明的数组(可变长度或其他)的指针是未定义的行为,如果它具有自动存储时间。这意味着您只能 return 指向作为参数传入或动态分配的可变长度数组的指针。
来自 C 标准(6.2.1 标识符的范围)
- ...(A function prototype is a declaration of a function that declares the types of its parameters.)
和(6.7.6.2 数组声明符)
- ...If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only
be used in declarations or type names with function prototype scope;
所以您可能不会像您展示的那样指定 return 函数类型。
考虑到 1) 函数可能没有 return 类型的数组和 2) 可变长度数组具有自动存储持续时间。因此,如果可以对这样的数组进行 returned,则该函数具有未定义的行为。参见 6.7.6.2 数组声明符:
2 If an identifier is declared as having a variably modified type, it
shall be an ordinary identifier (as defined in 6.2.3), have no
linkage, and have either block scope or function prototype scope. If
an identifier is declared to be an object with static or thread
storage duration, it shall not have a variable length array type.
我知道有两种方法可以解决您的问题。要么动态分配一个数组,然后 return 为其第一个元素分配一个指针。或者在结构中打包一个数组。在这种情况下,您可以 return 函数中的整个结构作为右值。
这样的函数原型在 C 中有效吗?
int (*func())[*];
如果是,我该如何定义这些函数?
技术上可以,但这不是一个好主意。
int * func(size_t s)
{
int array[s];
return array;
}
定义可变长度数组后,它与常规数组没有什么不同,因此当您尝试 return 它时,它会衰减为指针。返回指向局部变量的指针会导致未定义的行为。
您应该 return 指向不完整数组类型的指针,因为 *
可变长度数组的表示法仅在参数列表中有效。
示例原型和函数定义:
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);
请注意,return指向已在函数中声明的数组(可变长度或其他)的指针是未定义的行为,如果它具有自动存储时间。这意味着您只能 return 指向作为参数传入或动态分配的可变长度数组的指针。
来自 C 标准(6.2.1 标识符的范围)
- ...(A function prototype is a declaration of a function that declares the types of its parameters.)
和(6.7.6.2 数组声明符)
- ...If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;
所以您可能不会像您展示的那样指定 return 函数类型。
考虑到 1) 函数可能没有 return 类型的数组和 2) 可变长度数组具有自动存储持续时间。因此,如果可以对这样的数组进行 returned,则该函数具有未定义的行为。参见 6.7.6.2 数组声明符:
2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.
我知道有两种方法可以解决您的问题。要么动态分配一个数组,然后 return 为其第一个元素分配一个指针。或者在结构中打包一个数组。在这种情况下,您可以 return 函数中的整个结构作为右值。