Arrays 将C(gcc)中未知的数组大小typedef意外地完成为已知的数组大小类型
我遇到了一个有趣的情况–将不完整的数组大小typedef改为已知数组大小,例如:Arrays 将C(gcc)中未知的数组大小typedef意外地完成为已知的数组大小类型,arrays,c,incomplete-type,completion,Arrays,C,Incomplete Type,Completion,我遇到了一个有趣的情况–将不完整的数组大小typedef改为已知数组大小,例如: #include <stdio.h> typedef struct hi_ { int a, s; } hi[]; int main() { hi there = { {3,7}, {1,5} }; hi there2 = { {11,17} }; printf("«1» 1/a: %i, 1/s: %i\n2/a:%i 2/s:%i\n", the
#include <stdio.h>
typedef struct hi_
{
int a, s;
} hi[];
int main() {
hi there = { {3,7}, {1,5} };
hi there2 = { {11,17} };
printf("«1» 1/a: %i, 1/s: %i\n2/a:%i 2/s:%i\n", there[0].a, there[0].s, there[1].a, there[1].s);
printf("«2» 1/a: %i, 1/s: %i\n", there2[0].a, there2[0].s);
// Output:
// «1» 1/a: 3, 1/s: 7
// 2/a:1 2/s:5
// «2» 1/a: 11, 1/s: 17
}
#包括
类型定义结构hi_
{
INTA,s;
}嗨[];
int main(){
嗨,那里={3,7},{1,5};
hi-there2={11,17};
printf(“«1»1/a:%i,1/s:%i\n2/a:%i 2/s:%i\n”,那里[0].a,那里[0].s,那里[1].a,那里[1].s);
printf(“«2»1/a:%i,1/s:%i\n”,there2[0].a,there2[0].s);
//输出:
//«1»1/a:3,1/s:7
//2/a:1 2/s:5
//«2»1/a:11,1/s:17
}
我一点也不惊讶,因为在这个例子中,这种类型“无法完成””得到了非常强烈的支持。那么,为什么以及如何工作呢?问题中的
typedef
将hi
定义为一个数组(大小未知)
您引用的答案并不是说不完整的数组无法完成。它表示指向不完整数组的指针无法完成。它引用了以下标准:
…无法完成指向未知大小数组的指针类型,或由typedef
声明定义为未知大小数组的类型
这里有一个语法错误(见下文,“of a type”应为“to a type”),但答案说明了预期含义:
在上下文中阅读,它清楚地表明,“指向T
未知界数组的指针”不能“完成”为“指向NT
数组的指针”
语法错误是,“由typedef
声明定义为未知大小数组的类型”是由“或”作为“未知大小数组”的替代。因此,将“数组未知大小”替换为“类型…”将产生“由typedef
声明定义为未知大小数组的类型的指针类型…”,因此“to of”在语法上是不正确的,而不是预期的
判决可能是:
无法完成指向未知大小数组或由typedef
定义为未知大小数组的类型的指针类型
关于为何完成该类型,C 2018 6.7.9 22说:
如果初始化了未知大小的数组,则其大小由具有显式初始值设定项的最大索引元素确定。数组类型在其初始值设定项列表的末尾完成
因此,there
和there2
是大小未知的数组(因为hi
标识符是此类数组的别名),因此它们通过初始化完成
而是声明了指向
hi
,hi*p的指针代码>,即使初始化也无法完成。问题中的typedef
将hi
定义为一个数组(大小未知)
您引用的答案并不是说不完整的数组无法完成。它表示指向不完整数组的指针无法完成。它引用了以下标准:
…无法完成指向未知大小数组的指针类型,或由typedef
声明定义为未知大小数组的类型
这里有一个语法错误(见下文,“of a type”应为“to a type”),但答案说明了预期含义:
在上下文中阅读,它清楚地表明,“指向T
未知界数组的指针”不能“完成”为“指向NT
数组的指针”
语法错误是,“由typedef
声明定义为未知大小数组的类型”是由“或”作为“未知大小数组”的替代。因此,将“数组未知大小”替换为“类型…”将产生“由typedef
声明定义为未知大小数组的类型的指针类型…”,因此“to of”在语法上是不正确的,而不是预期的
判决可能是:
无法完成指向未知大小数组或由typedef
定义为未知大小数组的类型的指针类型
关于为何完成该类型,C 2018 6.7.9 22说:
如果初始化了未知大小的数组,则其大小由具有显式初始值设定项的最大索引元素确定。数组类型在其初始值设定项列表的末尾完成
因此,there
和there2
是大小未知的数组(因为hi
标识符是此类数组的别名),因此它们通过初始化完成
而是声明了指向hi
,hi*p的指针代码>,即使使用初始化也无法完成它。作为类比:inta[]={1,2,3}代码>声明大小为3整数的数组并对其进行初始化。你的代码也是如此。类型是完整的,只是它的大小没有在typedef中给出代码>声明大小为3整数的数组并对其进行初始化。你的代码也是如此。该类型是完整的,只是其大小未在typedef中给出。hi p[3]代码>是否将完成阵列,但不进行初始化?或者这是无效的,因为数组大括号是typedef的一部分?@PaulOgilvie:hi
是一个数组,因此hi something[3]
将是一个由3个数组组成的数组。(这违反了一条规则,即数组的元素必须是完整的,而hi
不是完整的。)因此,除非通过初始化,否则无法指定hi
的大小。@PaulOgilvie:您可以分配内存并通过将一个写入内存来创建hi
。按照C标准,它在内存中创建了一个这种类型的对象。但是您没有它的标识符,只有一个指向不完整的hi
类型的指针。我想不出任何办法