4

可能重复:
使用非常量初始化器定义全局变量

我有这个代码:

#include <stdio.h>
#include <stdlib.h>


int foo (int num, int i)
{
    static int* array = malloc(sizeof(int));  // ERROR HERE!!!
    printf("%d", array[i]);
    return 0;
}



int main(int argc, char *argv[])
{
    int i;
    for (i = 0; i < 2; i++) {
    foo(i, i);
    }

    return 0;
}

我将代码保存为ac源文件,我不能工作?error prompt:_

gcc -O2 -Wall test.c -lm -o test
test.c:4:1: error: initializer element is not constant

Compilation exited abnormally with code 1 at Sat Jan 05 21:33:56

但是,我将它保存为 C++ 源文件,它工作正常。为什么?有人可以向我解释吗?

4

4 回答 4

3

您不能static在 C 中使用非常量初始值设定项来初始化对象。

static int* array = malloc(sizeof(int));

                    ^ must be a constant

来自 C 标准:

(C99,6.7.8p4)“具有静态存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。”

于 2013-01-05T13:44:44.360 回答
2

staticC 和 C++ 标准以不同的方式处理具有存储持续时间的对象的初始化。C++ 允许静态初始化(即使用常量初始化)和动态初始化(即使用非常量表达式初始化),而C 只允许静态初始化——即使用常量表达式。

C++ 标准的相关部分是 6.7.4:

具有静态存储持续时间 (3.7.1) 的所有本地对象的零初始化 (8.5) 在任何其他初始化发生之前执行。一个 POD 类型(3.9)的本地对象,具有用常量表达式初始化的静态存储持续时间,在第一次进入它的块之前被初始化。[...]否则,此类对象在控件第一次通过其声明时被初始化;这样的对象在其初始化完成时被认为已初始化。(重点补充)

C++ 需要额外的“簿记”才能只运行一次初始化程序的动态部分(即调用malloc)。C标准中没有类似的“动态”规定:

所有具有静态存储持续时间的对象都应在程序启动之前进行初始化(设置为其初始值)。具有静态存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。

在没有并发的情况下,您可以重写代码以与 C 一起使用,如下所示:

int foo (int num, int i) {
    static int* array = NULL;
    if (!array) array = malloc(sizeof(int)); // No error
    printf("%d", array[i]);
    return 0;
}

现在您的代码负责“簿记”:它在执行分配之前进行array检查。NULL

于 2013-01-05T13:57:39.373 回答
1

C(与 C++ 不同)不允许使用非常量值初始化静态持续时间变量。

static int* array = malloc(sizeof(int));  // ERROR HERE!!!

C99 标准:第 6.7.8 节:

具有静态存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。

于 2013-01-05T13:46:33.373 回答
1

它在 C 中是非法的,但在 C++ 中是可以的,它们是不同的

可以改写如下:

static int* array = NULL;
if (array == NULL)
    array = malloc(sizeof(int));
于 2013-01-05T13:58:17.940 回答