可分析性
來自 cppreference.com
這是 C 語言的一個可選擴充套件,它限制了執行某些形式的未定義行為可能產生的結果,從而提高了對此類程式的靜態分析的有效性。僅當編譯器定義了預定義宏常量 __STDC_ANALYZABLE__(C11) 時,才能保證啟用可分析性。
如果編譯器支援可分析性,任何行為未定義的語言或庫構造都會被進一步分為關鍵(critical)和有界(bounded)未定義行為,並且所有有界 UB 的行為都將如下文所述受到限制。
目錄 |
[編輯] 關鍵未定義行為
關鍵 UB 是指可能在任何物件的邊界之外執行記憶體寫入或 volatile 記憶體讀取的未定義行為。具有關鍵未定義行為的程式可能容易受到安全漏洞的攻擊。
只有以下未定義行為是關鍵的:
- 訪問超出其生命週期的物件(例如,透過懸垂指標)
- 向其宣告不相容的物件進行寫入
- 透過函式指標呼叫函式,而該指標的型別與它所指向的函式的型別不相容
- 對左值表示式求值,但該表示式未指定物件
- 試圖修改字串字面量
- 解引用一個無效(空、不確定等)或越尾指標
- 透過非 const 指標修改 const 物件
- 使用無效引數呼叫標準庫函式或宏
- 使用非預期的引數型別呼叫可變引數標準庫函式(例如,呼叫 printf 時,引數的型別與其轉換說明符不匹配)
- 呼叫 longjmp,而在呼叫作用域中沒有 setjmp,或跨執行緒呼叫,或從 VM 型別的作用域內呼叫。
- 任何對已被 free 或 realloc 釋放的指標的使用
- 任何字串或寬字串庫函式訪問陣列越界
[編輯] 有界未定義行為
有界 UB 是指不能執行非法記憶體寫入的未定義行為,儘管它可能會陷入陷阱(trap)並可能產生或儲存不確定的值。
- 所有未被列為關鍵的未定義行為都是有界的,包括:
[編輯] 注意
有界未定義行為會停用某些最佳化:啟用可分析性進行編譯會保留原始碼的因果關係,而這種關係在其他情況下可能被未定義行為所破壞。
可分析性擴充套件允許,作為一種實現定義的行為,在發生陷阱(trap)時呼叫執行時約束處理器。
[編輯] 參考文獻
- C11 標準 (ISO/IEC 9899:2011)
- 6.10.8.3/1 條件性功能宏 (p: 177)
- 附錄 L 可分析性 (p: 652-653)