簡體   English   中英

sizeof(array) 在運行時如何工作?

[英]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 標准:

6.5.3.4

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM