在C中,static const int
和const 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
執行期間的複製指令?
在C中,static const int
和const 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
執行期間的複製指令?
鑑於這兩個常量在函數內部知道,什麼是從使它*a = 30;
停止編譯器?在這個例子中,b
和c
都不能有存儲。
如果有需要的存儲:
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。其他一切都是「由編譯器決定的」。
語言標準對此沒有提及。
然而,這很可能是編譯器將你的代碼轉換成這樣:
void f(int *a) {
*a = 30;
}
,因此在任何分配沒有內存(除了在指令空間,很明顯)。
static const int將在程序執行的整個生命週期中分配一次。
函數內部的const int將在每次輸入函數時分配到堆棧上,並在退出時從堆棧中釋放。
我可能會指出上述「然而,編譯器很可能會將您的代碼轉換爲:」是不正確的。如果您請求「靜態」存儲類,則沒有編譯器會忽略這一點,靜態變量可以指望在內存中傳遞指針 - 除其他原因外。
在你的例子中,它們的意思是相同的,正如@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;
}
這個用例我已經知道了,我在定義「真實」常量時想知道內存消耗。 – Spidey
如果OP的代碼字面上是寫的,那麼它確實可以像我的回答一樣「轉換」。 –
而我的gcc(4.6.2)和clang(3.0)將它從'-O'開始清除。 –
是的。我想我更關注的是問題的存儲類問題角度,而不是提供的代碼。 –