我用 C 撰寫了以下代碼
int main(){
int a = {1, 2, 3};
}
似乎分配的變數(在本例中為 a)始終采用第一個陣列元素的值。現在我想知道其他陣列元素是否被丟棄,或者在a之后寫入記憶體,從而導致緩沖區溢位。
uj5u.com熱心網友回復:
本宣告
int a = {1, 2, 3};
在語意上無效(它違反了下面提到的語意規則)。標量物件可能無法由具有多個初始化器的花括號初始化器串列初始化。
來自 C 標準(6.7.9 初始化)
11標量的初始值設定項應為單個運算式,可選地括在大括號中。物件的初始值是運算式的初始值(轉換后);與簡單賦值相同的型別約束和轉換適用,將標量的型別作為其宣告型別的非限定版本。
也就是說,花括號初始化器串列中的逗號被視為初始化器的分隔符,對于標量物件,只允許使用單個運算式。
當存在多個初始化器時,編譯器假定初始化的物件是一個集合。
要宣告一個陣列,您需要撰寫
int a[] = {1, 2, 3};
或者
int a[N] = {1, 2, 3};
其中N是等于或大于 3 的整數值。
uj5u.com熱心網友回復:
int a = {1, 2, 3}; 不是有效的 C 代碼。
這是C標準中所謂的約束違規,之后需要編譯器發出診斷訊息:
C17 6.7.9/2:
約束
任何初始值設定項都不應嘗試為未包含在正在初始化的物體中的物件提供值。
雖然這不是語法錯誤,但我們實際上可能會寫一些奇怪的廢話,例如int a = {1};使用單個大括號括起來的初始化程式。無論錯誤原因如何,結果都是相同的 - 編譯器必須針對所有約束和語法違規發出診斷訊息。
為避免浪費您的時間來解決此類無效的 C 代碼,請研究為初學者學習 C 推薦哪些編譯器選項?
至于像 gcc 和 clang 這樣的編譯器在面對這種非標準代碼時會做什么——它們似乎只是簡單地丟棄了多余的初始化程式。如果我使用 gcc/clang for x86 編譯此代碼并忽略診斷訊息:
int foo (void)
{
int a = {1, 2, 3};
return a;
}
生成的 x86 程式集是
mov eax, 1
ret
當轉換回 C 時,它 100% 相當于
int foo (void)
{
return 1;
}
重要的是要了解這是一個非標準的編譯器擴展,并且沒有保證或可移植的行為。
uj5u.com熱心網友回復:
int main(void)
{
int a[3] = {1, 2, 3};
printf("%d\n", a[0]);
return(0);
}
Output : 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/341259.html
上一篇:如何在PHP中獲取ContactForm7物件的屬性
下一篇:將字串值轉換為整數陣列
