英文:
What does a C array definition without size mean?
问题
以下是要翻译的代码部分:
int main()
{
int array[];
}
这只是一个未初始化的指针吗?还是一个具有小默认大小的数组?
哪些编译器支持此语法,以及为什么?我认为这可能导致混淆。
此外,在这里也提到了:
https://stackoverflow.com/q/76032903/509868
<!-- 请允许我继续 -->
英文:
Example:
int main()
{
int array[];
}
Is it just an uninitialized pointer? Or an array with a small default size?
Which compilers support this syntax, and why? I see this as a recipe for confusion.
Also mentioned here:
https://stackoverflow.com/q/76032903/509868
<!-- please let me continue -->
答案1
得分: 3
对于此声明要有效,需要存在一个初始化列表:int array[] = { ... };
。
否则,数组是不完整的,参考 C17 6.7.6.2:
> 如果大小未给出,数组类型是不完整的类型。
局部范围的不完整数组类型不是有效的声明,符合规范的编译器会生成诊断消息。只有在一些特殊情况下才允许不完整的数组类型:
-
函数声明可能包含一个不完整的数组类型,因为它会被调整为指向第一个元素的指针。调整后,数组不应具有不完整类型(也不应是具有不完整元素类型的数组类型)。
因此,
void func (int array[])
是有效的,等同于void func (int* array)
。 -
struct
的最后一个成员可以是不完整的数组类型,称为“柔性数组成员”。 -
作为文件范围数组在任何函数外部声明,在同一翻译单元后完成其类型或当具有外部链接时(
extern
等),引用另一翻译单元中的数组。
英文:
For this declaration to be valid, there needs to be an initializer list present:
int array[] = { ... };
.
Otherwise the array is incomplete, C17 6.7.6.2:
> If the size is not present, the array type is an incomplete type.
Incomplete array types at local scope are not valid declarations and a conforming compiler will raise a diagnostic message. Incomplete array types are only allowed in some special cases:
-
A function declaration may contain an incomplete array type since it gets adjusted to a pointer to the first element. After adjustment, the array should not have incomplete type (nor be of an array type with incomplete element type).
void func (int array[])
is therefore valid and equivalent tovoid func (int* array)
. -
The last member of a
struct
can be an incomplete array type, a so-called flexible array member. -
As a file scope array declared outside any function, with its type completed later in the same translation unit or when it has external linkage (
extern
etc), referring to an array in another translation unit.
答案2
得分: 2
根据其他答案的指示,在该上下文中,该代码在C中是非法的。
然而,如果声明包含初始化,那么数组具有适当的大小:
int array[] = {10, 20, 30}; // 数组大小为3
特殊情况是初始化为空时:
int array[] = {}; // 数组大小为0
在这种情况下,数组的大小为0。这在C中是不允许的,但一些编译器支持这样做。
int main()
{
int array[] = {};
printf("%zu", sizeof(array));
}
使用gcc
编译:OK,打印 0
使用gcc -pedantic
编译:错误:零或负大小数组
使用MS Visual Studio编译:错误:无法分配大小为0的常量大小数组
零大小的数组大多是无用的;它提供与灵活数组成员相同的功能,但是非标准的——仅支持与一些旧代码兼容。
英文:
As other answers indicate, the code is illegal in C in that context.
However, if the declaration includes initialization, then the array has proper size:
int array[] = {10, 20, 30}; // array has size 3
A special case is when the initialization is empty:
int array[] = {}; // array has size 0
In this case, the size of the array is 0. This is not allowed in C, but some compilers support this.
int main()
{
int array[] = {};
printf("%zu", sizeof(array));
}
Compiled by gcc
: OK, prints 0
Compiled by gcc -pedantic
: error: zero or negative size array
Compiled by MS Visual Studio: error: cannot allocate an array of constant size 0
A zero-size array is mostly useless; it provides the same functionality as flexible array member, but is non-standard — only supported for compatibility with some old code.
答案3
得分: 1
在你的代码中,int array[];
这样的构造方式在C语言中是非法的。
假设它是合法的:
Q: 它只是一个未初始化的指针吗?
A: 数组不是指针。如果这样的声明是合法的,它将是一个大小为零的数组。如果将 array
赋给一个指针,那个指针将指向一个大小为0的内存段。顺便说一下,通过使用 malloc(0)
实际上也是可能的,但那是另一回事。
Q: 它是一个具有小默认大小的数组吗?
A: 在C语言中没有默认大小。顺便问一下,那个“默认大小”会是多少呢?
Q: 哪些编译器支持这种语法,为什么?
A: 据我所知,没有理智的C编译器支持这个,有一个很好的理由。
英文:
The construct int array[];
as it appears in your code (in other words: as a stand-alone array) is illegal in C.
Supposing it were legal:
Q: Is it just an uninitialized pointer?
A: an array is not a pointer. If such a declaration were legal it would be an array of size zero. And if you'd assign array
to a pointer, the pointer would point to a segment of memory of size 0. BTW latter is actually possible by using malloc(0)
, but that's another story.
Q: Is it an array with a small default size?
A: Not there are no default sizes in C. BTW what would that default size be?
Q: Which compilers support this syntax, and why?
A: AFAIK no sane C compiler supports this for a good reason.
答案4
得分: 1
int array[];
声明一个具有不完整数组类型的 array
。
在函数内部(即块作用域),如果一个变量的声明没有标记为 extern
,且没有初始化器,但是声明为不完整数组类型,是不允许的。
在函数外部(即文件作用域),如果一个变量的声明没有标记为 extern
,且没有初始化器,但是声明为不完整数组类型,可以作为该变量的试探性定义。如果变量的类型在翻译单元结束时仍然不完整(即在当前编译结束时),它将会隐式初始化为 {0}
,使其具有一个元素(但由于类型在使用 sizeof
时仍然不完整,因此无法测量其大小)。
英文:
int array[];
declares array
with an incomplete array type.
Inside a function (i.e. at block scope), a declaration of a variable that is not declared extern
, and that has no initializer, but is declared with an incomplete array type is not allowed.
Outside a function (i.e. at file scope), a declaration of a variable that is not declared extern
, and that has no initializer, but is declared with an incomplete array type is allowed as a tentative definition of the variable. If the variable's type is still incomplete at the end of translation unit (i.e. at the end of the current compilation), it will be implicitly initialized with the initializer {0}
causing it to have one element (but its size cannot be measured with sizeof
because the type is still incomplete at the point where sizeof
is used).
答案5
得分: -1
我将其视为混淆的一种方法,这正是设计中不允许的原因。因此,没有编译器会支持这样做。数组的大小必须在数组声明中提供,或者通过立即初始化以便可以推导出大小。
英文:
> I see this as a recipe for confusion
Which is exactly why this is not allowed by design in the language. So no compiler will support this. The array must be known in size either by providing a size in the array declaration, or by immediate initialization so the size can be derived.
https://en.cppreference.com/w/cpp/language/array#Arrays_of_unknown_bound
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论