可分析性
来自 cppreference.cn
这是 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)