[英]How sizeof(array) works at runtime?
我讀過 C 中的 sizeof 運算符是在編譯時解釋的,因為在編譯時編譯器知道數組大小及其類型,sizeof 能夠計算數組占用的字節數。但是 sizeof 是如何處理以下代碼的:
#include<stdio.h>
#include<string.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int s=sizeof(a);
printf("%d",s);
return 0;
}
這里的數組大小在編譯時是未知的,那么它是如何正常工作的呢?
在 C89 中, sizeof
總是在編譯時計算。 自 C99 和可變長度 arrays 起,當可變長度數組是sizeof
操作數中表達式的一部分時,它是在運行時計算的。
對sizeof
操作數的求值也是如此:它在 C89 中不被求值,但在 C99 中如果操作數是可變長度數組類型,它就會被求值。 例如:
int n = 5;
sizeof (int [n++]);
// n is now 6
由於您將sizeof
應用於可變長度數組,其大小在編譯時並不完全已知,因此編譯器必須生成代碼以在運行時執行其中的一部分。
gcc 4.6.3 的高級優化器將您顯示的代碼轉換為
scanf ("%d", &n);
t12 = (long unsigned int) n;
t13 = t12 * 4;
__builtin_alloca (t13);
t16 = (unsigned int) t12;
t17 = t16 * 4;
s18 = (int) t17;
printf ("%d", s18);
這是否解釋了幕后發生的事情? (不要被看起來很傻的臨時變量數量嚇倒了——這是在我要求中間代碼轉儲時以static 單賦值形式出現的程序的產物。)
從 C99 標准:
sizeof
運算符產生其操作數的大小(以字節為單位),它可以是表達式或類型的括號名稱。 大小由操作數的類型決定。 結果是 integer。如果操作數的類型是可變長度數組類型,則計算操作數; 否則,不計算操作數,結果為 integer 常量。
在這種情況下, sizeof()
在運行時進行計算。 編譯器,因為它知道a
的大小基於數組聲明時n
的值,所以生成代碼以使用n
的適當值來為sizeof()
返回一個合理的值。
在 C99 中,並非所有sizeof()
的使用都可以在編譯時完全評估並減少為運行時常量。
我讀過 C 中的 sizeof 運算符在編譯時被解釋
除了 VLA 之外,所有情況下sizeof
都是在編譯時確定的。 對於 VLA, sizeof
在運行時計算。
不管sizeof
是在編譯時還是運行時計算的(或者更正式地說,它的結果是否是一個 integer 常量表達式), sizeof
的結果完全基於其參數的類型,而不是任何伴隨可變長度的隱藏數據數組本身。 當然,當sizeof
應用於可變修改類型時,生成的程序必須在某處跟蹤該大小。 但如果表達式足夠簡單並且它最初從中導出長度的變量不能改變,它可能會簡單地重新計算它。 或者,它可以將類型的大小存儲在某處(基本上在隱藏的局部變量中),但這不會以任何可觀察的方式連接到 VLA object(例如,如果您將指針傳遞給 VLA 的第一個元素到另一個 function,該指針不能用於恢復 VLA 長度)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.