第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

(為什么)使用未初始化的變量未定義的行為?

(為什么)使用未初始化的變量未定義的行為?

C C++
千巷貓影 2019-05-30 16:03:58
(為什么)使用未初始化的變量未定義的行為?如果我有:unsigned int x;x -= x;很明顯x 應(yīng)在這個(gè)表達(dá)式之后是零,但是無(wú)論我看哪里,他們都說(shuō)行為代碼的值是未定義的,而不僅僅是x(直至減法之前)。兩個(gè)問(wèn)題:是行為這段代碼確實(shí)沒(méi)有定義?(例如。代碼是否會(huì)在兼容的系統(tǒng)上崩潰(或者更糟)?如果是這樣,為什么C是否說(shuō)行為是未定義的,當(dāng)非常清楚的是x這里應(yīng)該是零?即什么是優(yōu)勢(shì)不定義這里的行為?顯然,編譯器可以簡(jiǎn)單地使用管它呢它認(rèn)為在變量中“方便”的垃圾值,它將按預(yù)期工作.這種方法有什么問(wèn)題嗎?
查看完整描述

4 回答

?
梵蒂岡之花

TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊

是的,這種行為是沒(méi)有定義的,但其原因與大多數(shù)人所知道的不同。

首先,使用統(tǒng)一值本身并不是未定義的行為,但值只是不確定的。如果值恰好是類(lèi)型的陷阱表示,則訪問(wèn)此值的是UB。無(wú)符號(hào)類(lèi)型很少有陷阱表示,因此在這方面相對(duì)安全。

使行為無(wú)法定義的是變量的一個(gè)附加屬性,即它“可以用register這就是它的地址永遠(yuǎn)不會(huì)被接受。這樣的變量被特別對(duì)待,因?yàn)橛行┘軜?gòu)有真正的CPU寄存器,它們有一種額外的狀態(tài),這種狀態(tài)是“未初始化的”,并且與類(lèi)型域中的值不相對(duì)應(yīng)。

編輯:標(biāo)準(zhǔn)的相關(guān)短語(yǔ)為6.3.2.1p2:

如果lvalue指定可以用寄存器存儲(chǔ)類(lèi)聲明的具有自動(dòng)存儲(chǔ)持續(xù)時(shí)間的對(duì)象(從未使用其地址),且該對(duì)象未初始化(未使用初始化器聲明,且未在使用前對(duì)其執(zhí)行賦值),則行為未定義。

為了讓它更清楚,下面的代碼在任何情況下都是合法的:

unsigned char a, b;memcpy(&a, &b, 1);a -= a;
  • 這里的地址

    a

    b

    所以它們的價(jià)值是不確定的。
  • unsigned char

    從未有不確定值只是未指定的陷阱表示,任何

    unsigned char

    可能會(huì)發(fā)生。
  • 最后

    a 

    持有價(jià)值

    0.

編輯2: ab具有未指定的值:

3.19.3 未指定值
在本國(guó)際標(biāo)準(zhǔn)不要求在任何情況下選擇值的相關(guān)類(lèi)型的有效值


查看完整回答
反對(duì) 回復(fù) 2019-05-30
?
慕標(biāo)琳琳

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超9個(gè)贊

C標(biāo)準(zhǔn)為編譯器提供了很大的空間來(lái)執(zhí)行優(yōu)化。如果假設(shè)程序的天真模型將未初始化的內(nèi)存設(shè)置為一些隨機(jī)位模式,并且所有操作都按照編寫(xiě)的順序執(zhí)行,那么這些優(yōu)化的結(jié)果可能會(huì)令人驚訝。

注意:以下示例僅有效,因?yàn)?code>x它的地址從來(lái)沒(méi)有被占用過(guò),所以它是“注冊(cè)式的”。如果x有陷阱表示;這種情況很少發(fā)生在無(wú)符號(hào)類(lèi)型(它至少需要“浪費(fèi)”一點(diǎn)存儲(chǔ)空間,并且必須有文檔記錄),而且不可能用于unsigned char。如果x如果有符號(hào)類(lèi)型,則實(shí)現(xiàn)可以定義在-(2)之間不是數(shù)字的位模式。恩-1-1)和2恩-1-1作為陷阱代表。

編譯器試圖將寄存器分配給變量,因?yàn)榧拇嫫鞅葍?nèi)存更快。由于程序可能使用比處理器擁有寄存器更多的變量,編譯器執(zhí)行寄存器分配,從而導(dǎo)致在不同時(shí)間使用相同寄存器的不同變量??紤]程序片段

unsigned?x,?y,?z;???/*?0?*/y?=?0;??????????????/*?1?*/z?=?4;??????????????/*?2?*/x?=?-?x;????????????/*?3?*/y?=?y?+?z;?
?????????/*?4?*/x?=?y?+?1;??????????/*?5?*/

當(dāng)計(jì)算第3行時(shí),x還沒(méi)有初始化,因此(編譯器的原因)第3行必須是某種僥幸,這是由于編譯器不夠聰明而無(wú)法解決的其他情況。自z不在第4行之后使用,并且x如果不在第5行之前使用,則可以對(duì)兩個(gè)變量使用相同的寄存器。因此,這個(gè)小程序被編譯成寄存器上的以下操作:

r1?=?0;r0?=?4;r0?=?-?r0;r1?+=?r0;r0?=?r1;

的最終價(jià)值x的最終值r0的最終價(jià)值y的最終值r1。這些值是x=-3和y=-4,而不是如果x已經(jīng)正確初始化了。

關(guān)于更詳細(xì)的示例,請(qǐng)考慮以下代碼片段:

unsigned?i,?x;for?(i?=?0;?i?<?10;?i++)?{
????x?=?(condition()???some_value()?:?-x);}

假設(shè)編譯器檢測(cè)到condition沒(méi)有副作用。自condition不修改x,編譯器知道循環(huán)中的第一次運(yùn)行不可能訪問(wèn)x因?yàn)樗€沒(méi)有初始化。因此,循環(huán)體的第一次執(zhí)行相當(dāng)于x = some_value()沒(méi)有必要測(cè)試條件。編譯器可能會(huì)編譯這段代碼,就好像您已經(jīng)編寫(xiě)了

unsigned?i,?x;i?=?0;?/*?if?some_value()?uses?i?*/x?=?some_value();for?(i?=?1;?i?<?10;?i++)?{
????x?=?(condition()???some_value()?:?-x);}

在編譯器中建模的方式是考慮任何依賴(lài)于x無(wú)論什么價(jià)值都是方便的只要x未初始化。由于未初始化變量的行為是未定義的,而不是僅具有未指定值的變量,所以編譯器不需要跟蹤任何方便的值之間的任何特殊的數(shù)學(xué)關(guān)系。因此,編譯器可以這樣分析上面的代碼:

  • 在第一次循環(huán)迭代中,

    x

    未初始化的

    -x

    被評(píng)估。
  • -x

    有未定義的行為,所以它的價(jià)值是什么-是方便。
  • 優(yōu)化規(guī)則

    condition ? value : value

    應(yīng)用,以便將此代碼簡(jiǎn)化為

    condition; value.

當(dāng)遇到問(wèn)題中的代碼時(shí),這個(gè)編譯器會(huì)在x = - x的值。-x什么都方便。這樣就可以優(yōu)化分配。

我還沒(méi)有尋找像上面所描述的編譯器的例子,但是這是好的編譯器嘗試做的優(yōu)化的類(lèi)型。我不會(huì)驚訝地遇到一個(gè)。下面是一個(gè)你的程序崩潰的編譯器的不太合理的例子。(如果您在某種高級(jí)調(diào)試模式下編譯您的程序,可能就不會(huì)那么難以置信了。)

此假設(shè)編譯器映射不同內(nèi)存頁(yè)中的每個(gè)變量,并設(shè)置頁(yè)屬性,以便讀取未初始化的變量會(huì)導(dǎo)致調(diào)用調(diào)試器的處理器陷阱。對(duì)變量的任何賦值首先要確保其內(nèi)存頁(yè)被正常映射。此編譯器不嘗試執(zhí)行任何高級(jí)優(yōu)化-它處于調(diào)試模式,目的是很容易地定位bug,如未初始化的變量。什么時(shí)候x = - x計(jì)算,則右側(cè)將引發(fā)陷阱并觸發(fā)調(diào)試器.


查看完整回答
反對(duì) 回復(fù) 2019-05-30
?
紫衣仙女

TA貢獻(xiàn)1839條經(jīng)驗(yàn) 獲得超15個(gè)贊

是的,程序可能會(huì)崩潰。例如,可能會(huì)出現(xiàn)陷阱表示(無(wú)法處理的特定位模式),這些表示可能會(huì)導(dǎo)致CPU中斷,而未處理的則可能導(dǎo)致程序崩潰。

(6.2.6.1在后期的C11草案中說(shuō))某些對(duì)象表示不需要表示對(duì)象類(lèi)型的值。如果對(duì)象的存儲(chǔ)值具有這樣的表示形式,并且由不具有字符類(lèi)型的lvalue表達(dá)式讀取,則該行為是未定義的。如果這樣的表示是由一個(gè)副作用產(chǎn)生的,該副作用通過(guò)不具有字符類(lèi)型的lvalue表達(dá)式修改對(duì)象的全部或任何部分,則該行為是未定義的。50)這種表示稱(chēng)為陷阱表示。


查看完整回答
反對(duì) 回復(fù) 2019-05-30
?
UYOU

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊

C標(biāo)準(zhǔn)并沒(méi)有說(shuō)使用未初始化的自動(dòng)存儲(chǔ)持續(xù)時(shí)間對(duì)象的值是未定義的行為。C 1999標(biāo)準(zhǔn)在6.7.8 10中說(shuō):“如果沒(méi)有顯式初始化具有自動(dòng)存儲(chǔ)持續(xù)時(shí)間的對(duì)象,那么它的值是不確定的?!?本段繼續(xù)定義靜態(tài)對(duì)象是如何初始化的,因此我們關(guān)注的唯一未初始化對(duì)象是自動(dòng)對(duì)象。)

3.17.2將“不定值”定義為“未指定值或陷阱表示”。3.17.3將“未指明價(jià)值”定義為“本國(guó)際標(biāo)準(zhǔn)未規(guī)定在任何情況下選擇價(jià)值的相關(guān)類(lèi)型的有效值”。

所以,如果未初始化unsigned int x具有未指定的值,則x -= x必須產(chǎn)生零。這就留下了一個(gè)問(wèn)題,那就是它是否是一個(gè)陷阱表示法。訪問(wèn)陷阱值確實(shí)會(huì)導(dǎo)致未定義的行為,如6.2.6.1 5所示。

某些類(lèi)型的對(duì)象可能有陷阱表示,例如浮點(diǎn)數(shù)的信令nans.但無(wú)符號(hào)整數(shù)是特殊的。根據(jù)6.2.6.2,無(wú)符號(hào)int的每個(gè)N值位表示2的冪,值位的每個(gè)組合表示0到2之間的值之一。N-1。因此,由于填充位中的某些值(例如奇偶校驗(yàn)位),無(wú)符號(hào)整數(shù)只能具有陷阱表示。

如果在目標(biāo)平臺(tái)上,無(wú)符號(hào)int沒(méi)有填充位,那么未初始化的無(wú)符號(hào)int不能有陷阱表示,而且使用它的值不會(huì)導(dǎo)致未定義的行為。


查看完整回答
反對(duì) 回復(fù) 2019-05-30
  • 4 回答
  • 0 關(guān)注
  • 873 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)