C 中文件范围内可变修改的数组

问题描述 投票:0回答:4

我有一些这样的代码:

static int a = 6;
static int b = 3;

static int Hello[a][b] =
{
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3}
};

但是当我编译它时,它说错误:

在文件范围内可变地修改“Hello”

怎么会发生这种事?我该如何解决它?

c arrays static
4个回答
94
投票

您不能拥有其大小作为变量给出的静态数组

这就是为什么常量应该是

#define
d:

#define a 6

这样预处理器会将

a
替换为
6
,使其成为有效声明。


10
投票

简单的答案:在文件范围内修改变量数组是不可能的

详细:

使其成为编译时积分常量表达式,因为必须在编译时指定数组长度。

像这样:

#define a 6
#define b 3

或者,遵循C99标准。并像 GCC 一样进行编译。

gcc -Wall -std=c99 test.c -o test.out

这里的问题是提供长度的可变长度数组可能未初始化,因此您会收到此错误。

简单

static int a = 6;
static int b = 3;

void any_func()
{
    int Hello [a][b]; // No need of initialization. No static array means no file scope.
}

现在使用 for 循环或任何循环来填充数组。

欲了解更多信息,只需一个演示

#include <stdio.h>

static int a = 6;
int main()
{
    int Hello[a] = {1, 2, 3, 4, 5, 6}; // See here initialization of the array 'Hello'. It's in the function
                                       // Scope, but still an error
    return 0;
}

编译

cd ~/c
clang -std=c99 vararr.c -o vararr

输出:

vararr.c:8:11: error: variable-sized object may not be initialized
int Hello[a]={1,2,3,4,5,6};
          ^
1 error generated.

如果您删除静态并提供初始化,那么它将生成如上所述的错误。

但是如果你保持静态和初始化那么它仍然会是一个错误。

但是如果你删除初始化并保留

static
,则会出现以下错误。

error: variable length array declaration not allowed at file scope
static int Hello[a];
           ^     ~
1 error generated.

因此在文件作用域中不允许使用可变长度数组声明,因此请使其在任何函数内成为函数或块作用域(但请记住使其成为函数作用域必须删除初始化)

注意:由于它带有

C
标签,因此将
a
b
用作
const
对您没有帮助,但在
C++
const
中效果很好。


3
投票

使用Clang/LLVM时,可以进行以下操作:

static const int a = 6;
static const int b = 3;

static int Hello[a][b] =
{
    {1, 2, 3},
    {1, 2, 3},
    {1, 2, 3},
    {1, 2, 3},
    {1, 2, 3},
    {1, 2, 3}
};

(要在生成的程序集中看到它,需要使用“Hello”,因此不会被优化掉。)

但是,如果选择 C99 模式 (-std=c99),则会生成错误。如果选择了 -pedantic,它只会生成警告(Wgnu-folding-constant)。

GCC 似乎不允许这样做(const 被解释为只读)。

参见这个问题的解释:

Linux GCC 中无故出现“Initializer element is not Constant”错误,编译 C


2
投票

是的,这很烦人:

const int len = 10;

int stuff[len];

给出错误。我尝试避免执行#define x,因为 const int 是声明常量的更好方法,但是在这些情况下,const int 不是真正的常量,即使编译器完全知道它是。

© www.soinside.com 2019 - 2024. All rights reserved.