未定义行为

科技工作者之家 2020-11-17

在计算机程序设计中,未定义行为是指执行某种计算机代码所产生的结果,这种代码在当前程序状态下的行为在其所使用的语言标准中没有规定。常见于翻译器对源代码存在某些假设,而执行时这些假设不成立的情况。

简介一些编程语言中,某些情况下存在未定义行为,以C和C++最为著名。在这些语言的标准中,规定某些操作的语义是未定义的,典型的例子就是程序错误的情况,比如越界访问数组元素。标准允许语言的具体实现做这样的假设:只要是匹配标准的程序代码,就不会出现任何类似的行为。具体到 C/C++ 中,编译器可以选择性地给出相应的诊断信息,但没有对此的强制要求:针对未定义行为,语言实现作出任何反应都是正确的,类似于数字逻辑中的无关项。虽然编译器实现可能会针对未定义行为给出诊断信息,但保证编写的代码中不引发未定义行为是程序员自己的责任。这种假设的成立,通常可以让编译器对代码作出更多优化,同时也便于做更多的编译期检查和静态程序分析。

有时候也可能存在对于未定义行为本身的限制性要求。例如,在CPU的指令集说明中可能将某些形式的指令定为未定义,但如果该CPU支持内存保护,说明中很可能会还会包含一条兜底的规则,要求任何用户态的指令都不会让操作系统的安全性受损;这样一来,在执行未定义行为的指令时,就允许CPU破坏用户寄存器,但不允许发生诸如切换到监控模式的操作。

和未指定行为(unspecified behavior)不同,未定义行为强调基于不可移植或错误的程序构造,或使用错误的数据。一个匹配标准的实现可以在假定未定义行为永远不发生(除了显式使用不严格遵守标准的扩展)的基础上进行优化,可能导致原本存在未定义行为(例如有符号数溢出)的程序经过优化后显示出更加明显的错误(例如死循环)。因此,这种未定义行为一般应被视为bug。1

作用如果某一操作在文档中被定为未定义行为,编译器就可以假设该操作在匹配标准的程序中永远不会发生。这样,编译器就可以得到更多的信息,获得更多优化程序的机会。

例如这样的C语言代码:

int foo(unsigned char x){ int value = 2147483600; /* 假设 int 是 32 位 */ value += x; if (value

科技工作者之家

科技工作者之家APP是专注科技人才,知识分享与人才交流的服务平台。