最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++未定義行為(undefined behavior)

 更新時(shí)間:2017年02月12日 11:50:21   作者:木子兮  
對(duì)于未定義行為,C++標(biāo)準(zhǔn)沒(méi)有明確規(guī)定編譯器們應(yīng)該怎么做,那么執(zhí)行的結(jié)果就是不可預(yù)料的。下面我們來(lái)詳細(xì)探討下

衡量一個(gè)人是否真正活著的根本方法,就是看他是否有意愿、有能力做出主動(dòng)的選擇。

在計(jì)算機(jī)程序設(shè)計(jì)中,未定義行為(undefined behavior)是指行為不可預(yù)測(cè)的計(jì)算機(jī)代碼。這是一些編程語(yǔ)言的一個(gè)特點(diǎn),最有名的是在C語(yǔ)言中。在這些語(yǔ)言中,為了簡(jiǎn)化標(biāo)準(zhǔn),并給予實(shí)現(xiàn)一定的靈活性,標(biāo)準(zhǔn)特別地規(guī)定某些操作的結(jié)果是未定義的,這意味著程序員不能預(yù)測(cè)會(huì)發(fā)生什么事。

一個(gè)問(wèn)題

此問(wèn)題摘自知乎:

對(duì)順序容器 ( vector ) 的訪(fǎng)問(wèn):

如果使用 operator[] 訪(fǎng)問(wèn)容器,下標(biāo)越界是未定義行為。
使用 at 訪(fǎng)問(wèn),下標(biāo)越界,則拋出一個(gè) out_of_range 異常。
下標(biāo)越界應(yīng)該是明顯錯(cuò)誤的,但是為什么 C++ 標(biāo)準(zhǔn)選擇把 operator[] 列為未定義行為,而加入at成員在對(duì)成員訪(fǎng)問(wèn)時(shí)進(jìn)行下標(biāo)檢查?

同樣摘取一些回答

回答一:

C++ 的設(shè)計(jì)理念之一,就是你不需要為你不使用的特性付出代價(jià)。如果你能確保你的下標(biāo)不越界,C++就不會(huì)進(jìn)行檢查。

回答二:

檢查就表示有運(yùn)算判斷的開(kāi)銷(xiāo),C++將效率放在第一位,假設(shè)用戶(hù)之前已經(jīng)對(duì)[]訪(fǎng)問(wèn)的下標(biāo)做過(guò)檢查了,在一個(gè)大量訪(fǎng)問(wèn)的for循環(huán)中,但是vector還是自作聰明的每次都判斷一次下標(biāo)越界,這個(gè)效率影響你可想而知!你會(huì)不會(huì)在這個(gè)情況下罵它管的太多呢。所以說(shuō)將所有的權(quán)利都交給你,vector不做太多自作聰明的處理。

什么是未定義

未定義行為(Undefined Behavior)是指語(yǔ)言標(biāo)準(zhǔn)未做規(guī)定的行為。同時(shí),標(biāo)準(zhǔn)也從沒(méi)要求編譯器判斷未定義行為,所以這些行為有編譯器自行處理,在不同的編譯器可能會(huì)產(chǎn)生不同的結(jié)果,又或者如果程序調(diào)用未定義的行為,可能會(huì)成功編譯,甚至一開(kāi)始運(yùn)行時(shí)沒(méi)有錯(cuò)誤,只會(huì)在另一個(gè)系統(tǒng)上,甚至是在另一個(gè)日期運(yùn)行失敗。當(dāng)一個(gè)未定義行為的實(shí)例發(fā)生時(shí),正如語(yǔ)言標(biāo)準(zhǔn)所說(shuō),“什么事情都可能發(fā)生”,也許什么都沒(méi)有發(fā)生。

下文會(huì)羅列C++中的一系列未定義結(jié)果和未定義行為,持續(xù)整理更新。

未定義的結(jié)果

1、當(dāng)我們賦給帶符號(hào)類(lèi)型一個(gè)超出它表示范圍的值時(shí),結(jié)果是未定義的。

signed char c2 = 256; // c2的值是未定義的

2、函數(shù)體之內(nèi)定義的變量:未初始化(uninitialized),其值undefined。

3、算術(shù)表達(dá)式有可能產(chǎn)生未定義的結(jié)果

數(shù)學(xué)性質(zhì)本身:除數(shù)為0
計(jì)算機(jī)的特點(diǎn):溢出;很多系統(tǒng)在編譯和運(yùn)行時(shí)都不報(bào)出溢出錯(cuò)誤,像其他未定義的行為一樣,溢出的結(jié)果是不可預(yù)知的。

未定義的行為

未定義行為,無(wú)法預(yù)估Runtime會(huì)發(fā)生什么(unpredictable:normal、crashing、incorrect results)。

1、解引用空指針、非法迭代器或者尾后迭代器都是未定義行為

2、訪(fǎng)問(wèn)一個(gè)無(wú)效數(shù)組索引,下標(biāo)越界

3、當(dāng)derived class對(duì)象經(jīng)由一個(gè)base class指針被刪除,而該base class帶著一個(gè)non-virtual析構(gòu)函數(shù),其結(jié)果是未定義的。

實(shí)際執(zhí)行時(shí)通常發(fā)生的是對(duì)象的derived成員沒(méi)有被銷(xiāo)毀。
4、在兩個(gè)異常同時(shí)存在的情況下,程序若不是結(jié)束執(zhí)行就是導(dǎo)致未定義行為。

5、釋放一個(gè)非new分配的內(nèi)存,或者將相同的指針值釋放多次,其行為是未定義的。

6、string s(s2,pos2); // s是string s2從下標(biāo)pos2開(kāi)始的字符拷貝,如果pos2>s2.size(),構(gòu)造函數(shù)的行為未定義

7、試圖比較兩個(gè)無(wú)關(guān)地址是未定義行為

8、對(duì)于那些沒(méi)有指定執(zhí)行順序的運(yùn)算符來(lái)說(shuō),如果表達(dá)式指向并修改了同一個(gè)對(duì)象,將會(huì)引發(fā)錯(cuò)誤并產(chǎn)生未定義的行為。

int i=0;
cout<<i<<" "<<++i<<endl; // 未定義
// 編譯器可能先求++i的值,再求i的值;也可能先求i的值,再求++i的值。注意與print函數(shù)的區(qū)別。
*beg=toupper(*beg++); // 未定義

9、對(duì)有符號(hào)數(shù)進(jìn)行左移操作可能會(huì)改變符號(hào)位的值,因此是一種未定義的行為。移位運(yùn)算符右側(cè)的運(yùn)算對(duì)象一定不能為負(fù),而且值必須嚴(yán)格小于結(jié)果的位數(shù),否則就會(huì)產(chǎn)生未定義的行為。

10、使用static_cast將void*轉(zhuǎn)換成其他類(lèi)型指針,必須確保轉(zhuǎn)換后所得的類(lèi)型就是指針?biāo)傅念?lèi)型。類(lèi)型一旦不符,將產(chǎn)生未定義行為。

double d;
void* p=&d;
double *dp=static_cast<double*>(p);

11、const_cast只能改變運(yùn)算對(duì)象的底層const,如果對(duì)象本身是一個(gè)常量,使用const_cast執(zhí)行寫(xiě)操作就會(huì)產(chǎn)生未定義行為。

12、不要使用get初始化另一個(gè)智能指針或?yàn)橹悄苤羔樫x值,否則將會(huì)產(chǎn)生兩個(gè)獨(dú)立的shared_ptr指向相同的內(nèi)存,這將產(chǎn)生未定義行為。

13、delete []p;如果忘記[],其行為是未定義的。 刪除單一對(duì)象的指針加[],其行為也是未定義的。

相關(guān)文章

  • 基于C++浮點(diǎn)數(shù)(float、double)類(lèi)型數(shù)據(jù)比較與轉(zhuǎn)換的詳解

    基于C++浮點(diǎn)數(shù)(float、double)類(lèi)型數(shù)據(jù)比較與轉(zhuǎn)換的詳解

    本篇文章是對(duì)C++中浮點(diǎn)數(shù)(float、double)類(lèi)型數(shù)據(jù)比較與轉(zhuǎn)換進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++基礎(chǔ) class、struct、union詳細(xì)

    C++基礎(chǔ) class、struct、union詳細(xì)

    這篇文章主要 給大家介紹的是C++基礎(chǔ) class、struct、union,主要由三部分組成,分別是、類(lèi)class、結(jié)構(gòu)體struct、共用體union,需要的朋友可以參考一下
    2021-09-09
  • C語(yǔ)言超詳細(xì)講解文件的操作

    C語(yǔ)言超詳細(xì)講解文件的操作

    C語(yǔ)言文件操作的方法有很多,函數(shù)也有很多你知道哪些呢?下面是小編為大家?guī)?lái)的C語(yǔ)言文件操作的方法,歡迎閱讀
    2022-04-04
  • c++中string和vector的詳細(xì)介紹

    c++中string和vector的詳細(xì)介紹

    這篇文章主要介紹了c++中string和vector的詳細(xì)介紹,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-09-09
  • C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    今天小編就為大家分享一篇關(guān)于C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2021-09-09
  • C++字符串反轉(zhuǎn)的幾種方法

    C++字符串反轉(zhuǎn)的幾種方法

    通過(guò)不同的方法,實(shí)現(xiàn)對(duì)所輸入字符串的反轉(zhuǎn),具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • 淺談使用Rapidxml 庫(kù)遇到的問(wèn)題和分析過(guò)程(分享)

    淺談使用Rapidxml 庫(kù)遇到的問(wèn)題和分析過(guò)程(分享)

    下面小編就為大家?guī)?lái)一篇淺談使用Rapidxml 庫(kù)遇到的問(wèn)題和分析過(guò)程(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • C++利用鏈表模板類(lèi)實(shí)現(xiàn)簡(jiǎn)易隊(duì)列

    C++利用鏈表模板類(lèi)實(shí)現(xiàn)簡(jiǎn)易隊(duì)列

    這篇文章主要為大家詳細(xì)介紹了C++利用鏈表模板類(lèi)實(shí)現(xiàn)一個(gè)簡(jiǎn)易隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C++基礎(chǔ)入門(mén)教程(四):枚舉和指針

    C++基礎(chǔ)入門(mén)教程(四):枚舉和指針

    這篇文章主要介紹了C++基礎(chǔ)入門(mén)教程(四):枚舉和指針,本文重點(diǎn)講解了指針,有幽默搞笑的語(yǔ)言描述了指針,需要的朋友可以參考下
    2014-11-11
  • c++中拷貝構(gòu)造函數(shù)的參數(shù)類(lèi)型必須是引用

    c++中拷貝構(gòu)造函數(shù)的參數(shù)類(lèi)型必須是引用

    如果拷貝構(gòu)造函數(shù)中的參數(shù)不是一個(gè)引用,即形如CClass(const CClass c_class),那么就相當(dāng)于采用了傳值的方式(pass-by-value),而傳值的方式會(huì)調(diào)用該類(lèi)的拷貝構(gòu)造函數(shù),從而造成無(wú)窮遞歸地調(diào)用拷貝構(gòu)造函數(shù)。因此拷貝構(gòu)造函數(shù)的參數(shù)必須是一個(gè)引用
    2013-07-07

最新評(píng)論

金乡县| 牡丹江市| 稻城县| 宜春市| 获嘉县| 宣武区| 门源| 孝义市| 凯里市| 安陆市| 宾阳县| 横山县| 通榆县| 扬中市| 阿拉善左旗| 长兴县| 沧州市| 白河县| 湛江市| 六安市| 精河县| 江山市| 青川县| 莲花县| 松潘县| 新源县| 洪湖市| 东城区| 江川县| 夹江县| 额尔古纳市| 广东省| 双江| 青州市| 隆回县| 双峰县| 上饶县| 城固县| 台中县| 准格尔旗| 赣榆县|