考慮以下定期呼叫的函式:
void func(void)
{
const int myConstArray[4] = {1, 2, 3, 4};
// Doing some operations including the above array
}
如果將 from 更改為myConstArrayto const,static const這是否會改變代碼的編譯方式?
uj5u.com熱心網友回復:
更改const為static const更改物件的存盤持續時間。當陣列const int myConstArray[4] = {1, 2, 3, 4};在函式內宣告時,它具有自動存盤持續時間,這意味著從其關聯塊的執行開始到塊的執行結束時為其保留記憶體。更改宣告以static const int myConstArray[4] = {1, 2, 3, 4};使其具有靜態存盤持續時間,這意味著為整個程式保留記憶體。
現在,如果程式不使用更長的存盤持續時間,那么編譯器不必做任何不同的事情。考慮這段代碼:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
return Table[x];
}
在這段代碼中,編譯器可以看到Table只用于查找一個值。因此,當函式不執行時,它不需要存在——無論記憶體是否保留,程式的行為都是一樣的Table,所以它是否被宣告都static沒有關系。
將其與此代碼進行比較:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
這里函式將地址傳遞給Tableto bar。編譯器不知道bar該地址將做什么。bar可能會存盤地址,以便稍后在程式中由其他例程使用。在這種情況下,是否存在很Table重要static。如果Tableis not static,它的生命周期不會超出 的執行范圍foo,因此以后不應使用它的地址(如果是,則程式行為未由 C 標準定義)。這意味著編譯器可以將堆疊空間用于Table. 但是,如果Table用 宣告static,它的地址可以在執行之后使用foo,所以編譯器必須為它保留記憶體,即使在執行foo結束之后。
最后,考慮這段代碼:
int foo(int x)
{
const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
由于Table未宣告static,因此每次foo呼叫時,Table它都是 C 標準語意中的一個新物件。此外,所有不同的物件必須具有不同的地址(除了包含物件開頭的子物件,例如陣列及其第一個元素或結構及其第一個成員)。因此,如果遞回呼叫,則會創建第二個bar并再次呼叫。由于這兩個物件必須不同,所以必須傳遞不同的地址。這意味著,如果沒有宣告,編譯器可能會被迫在每次呼叫時在堆疊上創建它的新實體。為避免這種情況,最好用宣告。fooTablebarTablebarTablestaticfooTablestatic
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/460296.html
上一篇:為什么我們不必像在C 中宣告靜態變數一樣宣告靜態函式?
下一篇:為什么給定常量和變數的位數不同?
