2013-01-05 35 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));