2013-01-05 32 views
4

可能重复:
Definition of global variables using a non constant initializer分配内存以静态变量只有一次

我有这样的代码:

#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; 
} 

我保存代码的C源文件,我无法工作? 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++源文件,它工作正常。为什么?有没有人可以向我解释?

+3

这是因为C和C++是不同的语言。在C中有些事情是可以的,在C中是不行的。这就是其中之一。 –

回答

2

C和C++标准对存储持续时间不同的对象进行初始化。 C++允许静态初始化(即用常量初始化)和动态初始化(即用非常量表达式初始化),而C只允许静态初始化 - 即用常量表达式。

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

任何其它初始化发生之前执行具有静态存储的持续时间(3.7.1)的所有本地对象的零初始化(8.5) 。初始化一个带有用constant-expressions初始化的静态存储持续时间的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; 
} 

现在你的代码是负责“簿记”:它在执行之前检查arrayNULL分配。

3

不能初始化static对象与非恒定初始化在C.

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

        ^must be a constant 

从C标准:

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

1

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

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

C99标准:节6.7.8:

所有在一个初始化表达式对于具有静态存储期限为常量表达式或字符串文字的对象。

1

IT'IS ilegal在C,但在C++确定,它们是不同的

可以写成代替如下:

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