我是 C 編程的新手,我很難理解為什么會這樣
#include <stdio.h>
int main() {
int l = -5;
char arr[l];
printf("content: %s; sizeof: %d\n", arr, sizeof(arr));
}
帶輸出:
content: ; sizeof: -5
而這不會:
#include <stdio.h>
int main() {
char arr[-5];
printf("content: %s; sizeof: %d\n", arr, sizeof(arr));
}
帶輸出:
name.c:6:10: error: size of array ‘arr’ is negative
6 | char arr[-5];
| ^~~
我也期待第一個示例出現錯誤,但我真的不知道這里發生了什么。
uj5u.com熱心網友回復:
兩個版本的程式都不符合 C 語言規范(即使在更正格式說明符以正確匹配size_t引數之后)。但是這兩種情況在語意上是不同的,它們違反了語言規范的不同規定。
先拿這個:
char arr[-5];
運算式-5是一個整型常量運算式,所以這是一個普通陣列(不是變長陣列)的宣告。它受 C17 語言規范第 6.7.6.2/1 段的約束,其中部分說明:
除了可選的型別限定符和關鍵字之外
static,[and]還可以分隔運算式 or*。如果它們分隔運算式(指定陣列的大小),則運算式應具有整數型別。如果運算式是一個常量運算式,它的值應該大于零。
(加了重點。)
這是語言約束的一部分,這意味著編譯器在觀察到違規時有義務發出診斷訊息。原則上,實作不需要拒絕包含違反約束的代碼,但如果他們接受這樣的代碼,那么語言不會定義結果。
另一方面,考慮
int l = -5;
char arr[l];
因為l不是一個常量運算式(即使l被宣告也不會const),上面討論的規定不適用,并且單獨地arr是一個變長陣列。這受規范第 6.7.6.2/5 條的約束,相關部分要求尺寸運算式:
每次評估時,它的值都應大于零
該程式違反了該規定,但它是語意規則,而不是語言約束,因此編譯器沒有義務對其進行診斷,更不用說拒絕代碼了。在一般情況下,編譯器無法識別或診斷違反此特定規則的行為,但原則上,它可以在此特定情況下這樣做。如果它接受代碼,則運行時行為未定義。
-5當您在特定硬體上使用特定的 C 實作編譯和運行該程式時,為什么該程式會發出,這不是由 C 建立的。它可能由您的實作指定,也可能不是。程式中的微小變化或 C 實作的不同版本可能會產生不同的結果。
總的來說,這是 C 拒絕牽你的手的又一個例子。新編碼人員和那些習慣于解釋語言和虛擬機的人似乎經常期望系統的某些組件在他們撰寫錯誤代碼時通知他們。有時確實如此,但有時它只是使用那些可能與程式員所想的相似或不相似的糟糕代碼來執行某些操作。有效的 C 編程需要注意細節。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/370128.html
下一篇:我需要一個handleDelete過濾器函式來回應onclick按鈕。我可以為一個物件陣列撰寫代碼,但這是一個物件物件
