2013-01-12 67 views
3

在C中,static const intconst int之間在內存分配方面有什麼區別?函數範圍內的常量靜態變量情況下的內存分配

void f(int *a) 
{ 
    static const int b = 10; 
    const int c = 20; 

    *a = b + c; 
} 

請問b只消耗sizeof(int)?和c,它會消耗sizeof(int)20值和sizeof(int),再加上f執行期間的複製指令?

回答

1

鑑於這兩個常量在函數內部知道,什麼是從使它*a = 30;停止編譯器?在這個例子中,bc都不能有存儲。

如果有需要的存儲:

static const int b = 10; 

將佔用一個的sizeof(int)的[可能更多的空間由於用於填充,取決於之前什麼來,並在數據部分a之後,並有沒有說明編譯器將爲任何給定的場景提供多少填充 - 任何使編譯器所針對的系統「在工作」的必要條件)。根據系統的體系結構,可能需要將代碼設置爲b = 10 [請參閱下面的大小]。

const int c = 20; 

將可能佔用的sizeof(int)的堆棧上的字節,但也將有代碼來初始化b 20 - 這可能是任何小數目 - 2,3,5,6,7,8 ,16或某些類型,這取決於處理器架構和完成該工作所需的工具類型。當然,編譯器可以直接在需要的地方直接使用20個。

但是,編譯器所需要的就是* a被設置爲30。其他一切都是「由編譯器決定的」。

5

語言標準對此沒有提及。

然而,這很可能是編譯器將你的代碼轉換成這樣:

void f(int *a) { 
    *a = 30; 
} 

,因此在任何分配沒有內存(除了在指令空間,很明顯)。

1

static const int將在程序執行的整個生命週期中分配一次。

函數內部的const int將在每次輸入函數時分配到堆棧上,並在退出時從堆棧中釋放。

我可能會指出上述「然而,編譯器很可能會將您的代碼轉換爲:」是不正確的。如果您請求「靜態」存儲類,則沒有編譯器會忽略這一點,靜態變量可以指望在內存中傳遞指針 - 除其他原因外。

+0

如果OP的代碼字面上是寫的,那麼它確實可以像我的回答一樣「轉換」。 –

+0

而我的gcc(4.6.2)和clang(3.0)將它從'-O'開始清除。 –

+0

是的。我想我更關注的是問題的存儲類問題角度,而不是提供的代碼。 –

0

在你的例子中,它們的意思是相同的,正如@Oli所提到的那樣,編譯器會優化它,使得實際的代碼甚至可能在最終代碼中沒有它。

但這裏是不同的使用情況: -

int func1(int v) { 
const int c_i = compute_some_things(v);/* calculate the c_i everytime we enter this function */ 
return c_i = v + c_i; 
} 


int func2(int e) { 
static const int c_i = compute_some_things_one_time();/* c_i is calculated ONCE, the next time, the value of c_i is retained every time the function is entered */ 
return c_i = e + c_i; 
} 
+0

這個用例我已經知道了,我在定義「真實」常量時想知道內存消耗。 – Spidey