C 编译错误:“可变大小的对象可能未初始化”

发布于 2024-09-06 13:37:07 字数 101 浏览 10 评论 0 原文

为什么我使用以下代码收到错误“可变大小的对象可能未初始化”?

int boardAux[length][length] = {{0}};

Why do I receive the error "Variable-sized object may not be initialized" with the following code?

int boardAux[length][length] = {{0}};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

好多鱼好多余 2024-09-13 13:37:08

我假设您使用的是 C99 编译器(支持动态大小的数组)。您代码中的问题是,当编译器看到您的变量声明时,它无法知道数组中有多少个元素(我在这里还假设,从编译器错误中 length 不是编译时间常数)。

您必须手动初始化该数组:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );

I am assuming that you are using a C99 compiler (with support for dynamically sized arrays). The problem in your code is that at the time when the compilers sees your variable declaration it cannot know how many elements there are in the array (I am also assuming here, from the compiler error that length is not a compile time constant).

You must manually initialize that array:

int boardAux[length][length];
memset( boardAux, 0, length*length*sizeof(int) );
相思故 2024-09-13 13:37:08

您收到此错误是因为在 C 语言中不允许使用具有可变长度数组的初始值设定项。您收到的错误消息基本上说明了一切。

6.7.8 初始化

...

3 要初始化的实体的类型应为
未知大小的数组或对象
不是可变长度的类型
数组类型。

You receive this error because in C language you are not allowed to use initializers with variable length arrays. The error message you are getting basically says it all.

6.7.8 Initialization

...

3 The type of the entity to be initialized shall be
an array of unknown size or an object
type that is not a variable length
array type.

夜清冷一曲。 2024-09-13 13:37:08

这会给出错误:

int len;
scanf("%d",&len);
char str[len]="";

这也会给出错误:

int len=5;
char str[len]="";

但这工作正常:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

您需要按以下方式输入值:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";

This gives error:

int len;
scanf("%d",&len);
char str[len]="";

This also gives error:

int len=5;
char str[len]="";

But this works fine:

int len=5;
char str[len]; //so the problem lies with assignment not declaration

You need to put value in the following way:

str[0]='a';
str[1]='b'; //like that; and not like str="ab";
疯狂的代价 2024-09-13 13:37:08

声明数组后,

int boardAux[length][length];

将初始值分配为零的最简单方法是使用 for 循环,即使它可能有点长

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}

After declaring the array

int boardAux[length][length];

the simplest way to assign the initial values as zero is using for loop, even if it may be a bit lengthy

int i, j;
for (i = 0; i<length; i++)
{
    for (j = 0; j<length; j++)
        boardAux[i][j] = 0;
}
半枫 2024-09-13 13:37:08

变长数组是编译器在编译时不知道其长度的数组。在您的情况下 length 是一个变量。我得出这样的结论,因为如果 length 是一个定义为文字整数的预处理器宏,那么您的初始化将起作用。 1989 年的第一个 C 语言标准不允许可变长度数组,它们是在 1999 年添加的。 C 标准仍然不允许使用像您这样的表达式来初始化它们(尽管有人可能会认为它可以或应该允许)。

初始化变量数组的最佳方法如下:

int boardAux[length][length];
memset( boardAux, 0, sizeof(boardAux) );

memset 是一个非常快速的标准库函数,用于初始化内存(在上述情况下为 0)。 sizeof(boardAux) 返回boardAux 占用的字节数。 sizeof 始终可用,但 memset 需要 #include 。是的 - sizeof 允许可变大小的对象作为参数。

请注意,如果您有一个普通数组(不是可变长度)并且只想将内存初始化为零,则您永远不需要嵌套括号,您可以像这样简单地初始化它:

struct whatEver name[13][25] = {0};

Variable length arrays are arrays whose length is not known by the compiler at compile time. In your case length is a variable. I conclude this, because if length was a e.g. preprocessor macro defined as a literal integer your initialization would work. The first C language standard from 1989 did not allow variable length arrays, they were added in 1999. Still the C standard does not allow these to be initialized with an expression like yours (although one could argue that it could or should allow it).

The best way to initialize a variable array is like this:

int boardAux[length][length];
memset( boardAux, 0, sizeof(boardAux) );

memset is a very fast standard library function for initializing memory (to 0 in the above case). sizeof(boardAux) returns the number of bytes occupied by boardAux. sizeof is always available but memset requires #include <string.h>. And yes - sizeof allows a variable sized object as argument.

Note that if you have a normal array (not variable length) and just want to initialize the memory to zero you never need nested brackets, you can initialize it simply like this:

struct whatEver name[13][25] = {0};
小ぇ时光︴ 2024-09-13 13:37:08

数组未使用指定的内存进行初始化,anf 会引发错误
可变大小的数组可能无法初始化
我更喜欢通常的初始化方式,

for (i = 0; i < bins; i++)
        arr[i] = 0;

The array is not initialized with the memory specified anf throws an error
variable sized array may not be initialised
I prefer usual way of initialization,

for (i = 0; i < bins; i++)
        arr[i] = 0;
阳光下慵懒的猫 2024-09-13 13:37:08

在 C23 之前,不允许初始化可变长度数组,

int boardAux[length][length] = {{0}}; // Error

因此您必须随后手动初始化它。零初始化通常使用memset来完成。

从 C23 开始,变长数组的初始化规则发生了变化:

6.7.10 初始化

  • 要初始化的实体类型应为未知大小的数组或完整的对象类型。可变长度数组类型的实体不得初始化,除非使用空初始化器。未知大小的数组不得由空初始化器初始化。
  • 这意味着,从 C23 开始,您可以初始化 VLA,但只能使用空初始化程序对其进行零初始化。

    int boardAux[length][length] = {}; // OK since C23
    // memset( boardAux, 0, length*length*sizeof(int) ); // No longer needed
    

    Prior to C23 it wasn't allowed to initialize a variable length array

    int boardAux[length][length] = {{0}}; // Error
    

    You therefore had to manually initialize it afterwards. Zero-initializing was often done with a memset.

    Since C23, the initialization rules for variable length arrays have changed:

    6.7.10 Initialization

    1. The type of the entity to be initialized shall be an array of unknown size or a complete object type. An entity of variable length array type shall not be initialized except by an empty initializer. An array of unknown size shall not be initialized by an empty initializer.

    This means that, since C23, you may initialize a VLA, but only with an empty initializer to zero-initialize it.

    int boardAux[length][length] = {}; // OK since C23
    // memset( boardAux, 0, length*length*sizeof(int) ); // No longer needed
    
    昔日梦未散 2024-09-13 13:37:08

    问题已经得到解答,但我想指出另一种解决方案,该解决方案快速且在运行时不改变长度的情况下有效。在 main() 之前使用宏 #define 来定义长度,并且在 main() 中您的初始化将起作用:

    #define length 10
    
    int main()
    {
        int boardAux[length][length] = {{0}};
    }
    

    宏在实际编译之前运行,长度将是编译时常量(如 David Rodríguez 在他的回答中提到的)。它实际上在编译之前会将 length 替换为 10。

    The question is already answered but I wanted to point out another solution which is fast and works if length is not meant to be changed at run-time. Use macro #define before main() to define length and in main() your initialization will work:

    #define length 10
    
    int main()
    {
        int boardAux[length][length] = {{0}};
    }
    

    Macros are run before the actual compilation and length will be a compile-time constant (as referred by David Rodríguez in his answer). It will actually substitute length with 10 before compilation.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文