?
This document uses PHP Chinese website manual Release
這種對 C 語言的可選擴(kuò)展限制了執(zhí)行某些形式的未定義行為的潛在結(jié)果,這提高了此類程序的靜態(tài)分析的有效性。如果預(yù)定義的宏常量__STDC_ANALYZABLE__
(C11)由編譯器定義,則只能保證可分析性。
如果編譯器支持可分析性,那么其行為未定義的任何語言或庫構(gòu)造會進(jìn)一步分類為關(guān)鍵和有界的未定義行為,并且所有有界 UB 情況的行為都受到限制,如下所述。
嚴(yán)重的 UB 是未定義的行為,可能會執(zhí)行內(nèi)存寫入或讀取任何對象邊界的易失性內(nèi)存。具有嚴(yán)重未定義行為的程序可能容易受到安全漏洞攻擊。
只有以下未定義的行為至關(guān)重要:
訪問其生命周期之外的對象(例如,通過懸掛指針)
寫入聲明不兼容的對象
函數(shù)通過一個函數(shù)指針調(diào)用,該指針的類型與它指向的函數(shù)的類型不兼容
評估左值表達(dá)式,但不指定對象
嘗試修改字符串文字
解引用無效(空,不確定等)或過去結(jié)束指針
通過非const指針修改const對象
使用無效參數(shù)調(diào)用標(biāo)準(zhǔn)庫函數(shù)或宏
使用意外的參數(shù)類型調(diào)用可變參數(shù)標(biāo)準(zhǔn)庫函數(shù)(例如,printf
使用與其轉(zhuǎn)換說明符不匹配的參數(shù)調(diào)用)
longjmp
沒有setjmp
調(diào)用范圍,跨線程或VM類型的范圍內(nèi)。
任何使用由free
or 釋放的指針realloc
任何字符串或?qū)捵址畮旌瘮?shù)都會訪問數(shù)組越界
有界 UB 是未定義的行為,不能執(zhí)行非法的內(nèi)存寫入,盡管它可能會陷入并可能產(chǎn)生或存儲不確定的值。
所有未定義的行為都未被列為關(guān)鍵性的,包括
多線程數(shù)據(jù)競賽
使用具有自動存儲持續(xù)時間的不確定值
嚴(yán)格的走樣違規(guī)
錯位的對象訪問
有符號整數(shù)溢出
無序的副作用修改相同的標(biāo)量或修改并讀取相同的標(biāo)量
浮點到整數(shù)或指針到整數(shù)的轉(zhuǎn)換溢出
按位移動一個負(fù)數(shù)或太多的位數(shù)
整數(shù)除以零
使用void表達(dá)式
直接分配或memcpy
不精確重疊的對象
限制違規(guī)
所有未定義的行為都不在關(guān)鍵列表中。
注意
有界的未定義行為會禁用某些優(yōu)化:啟用可分析性的編譯會保留源代碼因果關(guān)系,否則可能會違反未定義的行為。
分析性擴(kuò)展允許在發(fā)生陷阱時調(diào)用運(yùn)行時約束處理程序,作為實現(xiàn)定義的行為的一種形式。
C11標(biāo)準(zhǔn)(ISO / IEC 9899:2011):
6.10.8.3/1條件特征宏(p:177)
附件L可分析性(p:652-653)