![](/img/trans.png)
[英]sizeof operator in conjunction with variable-length array as function arguments
[英]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
為它取一個規范性引用的克隆詞:
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.