St.*_*rio 2 c arrays language-lawyer flexible-array-member
GCC 编译函数返回具有灵活数组成员的结构。标准在 6.7.2.1 中给出了如何处理此类结构的定义:
在大多数情况下,灵活数组成员会被忽略。特别是,该结构的大小就像省略了柔性阵列成员一样,只是它可能具有比省略所暗示的更多的尾部填充。
由于具有灵活数组成员的结构的大小已知,因此根据 6.2.5 中给出的完整性定义,类型是完整的:
在翻译单元内的各个点,对象类型可能是不完整的(缺乏足够的信息来确定该类型的对象的大小)或完整的(具有足够的信息)。37)
另外,6.5.2.2
表示被调用函数 96) 的表达式应具有指向返回 void 或返回除数组类型之外的完整对象类型的函数的类型指针。
因此返回具有灵活数组成员的 s 应该是合法的struct。
如何修复下面的示例以使其正常工作(我需要具有灵活数组成员的堆栈分配结构):
#include <stdio.h>
struct test{
size_t sz;
char data[];
};
struct test get_test(void){
int sz = 5;
char data[5] = "test";
struct test test = {.sz = 5};
//How to copy char data[5] into the struct test test?
return test;
}
int main(void){
struct test tst = get_test();
printf("%s\n", tst.data);
}
Run Code Online (Sandbox Code Playgroud)
是的,返回这样的值是有效的 C,但不会复制任何数组元素。自动变量的行为就好像它确实分配了长度为 1 的数组(因为数组长度 0 在标准 C 中无效),但访问将具有 UB -对象的.data[0]实际大小.data[0]可能包括甚至更多连续元素 - 或不连续元素。(C11 6.7.2.1p18)。
不可能定义一个在标准 C中的灵活数组成员中包含任何内容的自动变量(扩展可能并且确实存在)!
赋值也是有效的(因此也返回),但是灵活数组成员在赋值后将再次包含不确定的值(C11 6.7.2.1p25)。