簡體   English   中英

可變長度數組類型的sizeof運算符

[英]Sizeof operator with variable-length array type

根據cppreference

如果表達式的類型是可變長度數組類型,則將在運行時對表達式進行求值,並計算要求值的數組的大小。

這意味着:如果表達式的類型是VLA類型,則對表達式進行求值。 例如:

#include <stdio.h>

int main() {
    int i = 0;
    int a[i];
    printf("%zu\n",sizeof(a[i++]));
    printf("%d\n",i); // Here, print 0 instead of 1
    return 0;
}

因此,根據參考,此處i變為1 但是,使用我的GCC編譯器, i打印為0

請參閱Wandbox演示

首先,請注意,數組不能為零,無論是否為VLA。 因此,您的代碼將調用未定義的行為。

C11 6.7.6.2/5

“如果size是一個不是整數常量表達式的表達式:“ /-/” ...每次對其進行求值時,其值都應大於零。


至於實際問題, a[i++]int類型,而不是VLA類型。

為了產生副作用,您必須涉及VLA數組類型本身,例如sizeof(a) 只有這樣,才對操作數進行副作用評估。 一個例子來說明這一點:

#include <stdio.h>

int main() {
    int i=1, j=1;
    int a[i][j];
    int b[1][1];

    (void) sizeof(a[--i]);
    (void) sizeof(b[--j]);
    printf("%d %d", i, j);

    return 0;
}

由於VLA計算了第一個sizeof因此i最終為0,但是j仍為1,因為--j是常規數組的sizeof一部分。

您的示例中sizeof的表達式是int,而不是vla。 如果是vla,則所有方法都可以工作:

#include <stdio.h>

int main() {
    int i = 5;
    int a[i][i];
    printf("%zu\n",sizeof(a[--i]));
    printf("%d\n",i); // Here, print 4
    return 0;
}

來自C Standards#6.5.3.4p2 [ 強調我的 ]

sizeof運算符產生其操作數的大小(以字節為單位),該操作數可以是表達式或類型的括號名稱。 大小由操作數的類型確定。 結果是一個整數。 如果操作數的類型是可變長度數組類型,則對操作數求值; 否則,不評估操作數,結果為整數常量

在表達式中:

sizeof(a[i++])

a[i++]不是VLA,而是下標運算符表達式,其結果為整數。 因此,不對操作數求值,並且出於相同的原因,編譯器會在此語句上給出警告:

warning: expression with side effects has no effect in an unevaluated context

為它取一個規范性引用的克隆詞:

6.5.3.4-sizeof和_Alignof運算符

sizeof運算符產生其操作數的大小(以字節為單位),該操作數可以是表達式或類型的括號名稱。 大小由操作數的類型確定。 結果是一個整數。 如果操作數的類型是可變長度數組類型,則對操作數求值; 否則,不評估操作數,結果為整數常量。

如果您修復示例以生成具有VLA類型的表達式,則可以評估這種情況

#include <stdio.h>

int main() {
    int i = 1;
    int a[5][i];
    printf("%zu\n",sizeof(a[i++]));
    printf("%d\n",i);
    return 0;
}

因為i遞增,所以在最后一行打印2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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