日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

变量的初始化与使用C语言程序注释,c - (为什么)使用未初始化的变量未定义行为?...

發(fā)布時間:2023/12/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 变量的初始化与使用C语言程序注释,c - (为什么)使用未初始化的变量未定义行为?... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C標準為編譯器提供了很大的優(yōu)勢來執(zhí)行優(yōu)化。 如果您假設(shè)一個簡單的程序模型,其中未初始化的內(nèi)存被設(shè)置為某個隨機位模式,并且所有操作都按照它們的寫入順序執(zhí)行,那么這些優(yōu)化的后果可能會令人驚訝。

注意:以下示例僅有效,因為x從未使用其地址,因此它是“類似寄存器”。 如果x = - x的類型具有陷阱表示,它們也將有效; 這對于無符號類型來說很少見(它需要“浪費”至少一位存儲空間,并且必須記錄在案),而-x則不可能。如果x有簽名類型,那么實現(xiàn)可以定義不是 - (2n-1-1)和2n-1-1之間的數(shù)字作為陷阱表示。 見Jens Gustedt的回答。

編譯器嘗試將寄存器分配給變量,因為寄存器比內(nèi)存快。 由于程序可能使用比處理器具有寄存器更多的變量,因此編譯器執(zhí)行寄存器分配,這導(dǎo)致在不同時間使用相同寄存器的不同變量。 考慮程序片段

unsigned x, y, z; /* 0 */

y = 0; /* 1 */

z = 4; /* 2 */

x = - x; /* 3 */

y = y + z; /* 4 */

x = y + 1; /* 5 */

當(dāng)評估第3行時,x = - x尚未初始化,因此(編譯器的原因)第3行必須是由于編譯器不夠聰明的其他條件而不能發(fā)生的某種僥幸。 由于在第4行之后未使用-x,并且在第5行之前未使用x,因此可以對兩個變量使用相同的寄存器。 所以這個小程序編譯成寄存器上的以下操作:

r1 = 0;

r0 = 4;

r0 = - r0;

r1 += r0;

r0 = r1;

最終值x = - x是最終值-x,最終值x是最終值x.這些值是x = -3和y = -4,而不是5和4,如果x = some_value()已經(jīng)發(fā)生 正確初始化。

有關(guān)更詳細的示例,請考慮以下代碼片段:

unsigned i, x;

for (i = 0; i < 10; i++) {

x = (condition() ? some_value() : -x);

}

假設(shè)編譯器檢測到x = - x沒有副作用。 由于-x不修改x,編譯器知道第一次循環(huán)運行不可能訪問x,因為它尚未初始化。 因此,循環(huán)體的第一次執(zhí)行相當(dāng)于x = some_value(),無需測試條件。 編譯器可以編譯此代碼,就像您編寫的那樣

unsigned i, x;

i = 0; /* if some_value() uses i */

x = some_value();

for (i = 1; i < 10; i++) {

x = (condition() ? some_value() : -x);

}

這可以在編譯器內(nèi)建模的方式是考慮依賴于x = - x的任何值都具有方便的值,只要-x未初始化即可。 因為未初始化變量未定義時的行為,而不是僅具有未指定值的變量,編譯器不需要跟蹤任何方便值之間的任何特殊數(shù)學(xué)關(guān)系。 因此編譯器可以用這種方式分析上面的代碼:

在第一次循環(huán)迭代期間,x = - x在評估-x時未初始化。

x = - x具有未定義的行為,因此它的值是任何方便的。

優(yōu)化規(guī)則? 價值:價值適用,所以這段代碼可以簡化為; 值。

當(dāng)遇到問題中的代碼時,同一個編譯器會分析當(dāng)評估x = - x時,-x的值是方便的。 因此,可以優(yōu)化分配。

我沒有找到一個行為如上所述的編譯器的例子,但它是優(yōu)秀的編譯器試圖做的優(yōu)化。 遇到一個我不會感到驚訝。 這是程序崩潰的編譯器的一個不太合理的例子。 (如果在某種高級調(diào)試模式下編譯程序,可能不會令人難以置信。)

這個假設(shè)的編譯器將每個變量映射到不同的內(nèi)存頁面并設(shè)置頁面屬性,以便從未初始化的變量讀取會導(dǎo)致調(diào)用調(diào)試器的處理器陷阱。 首先對變量賦值,確保其內(nèi)存頁面正常映射。 此編譯器不會嘗試執(zhí)行任何高級優(yōu)化 - 它處于調(diào)試模式,旨在輕松定位諸如未初始化變量之類的錯誤。 當(dāng)評估x = - x時,右側(cè)會導(dǎo)致陷阱并且調(diào)試器將啟動。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的变量的初始化与使用C语言程序注释,c - (为什么)使用未初始化的变量未定义行为?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。