未定义行为

维基百科,自由的百科全书
跳转至: 导航搜索

计算机程序设计中,未定义行为英语undefined behavior)是指行为不可预测的计算机代码。这是一些编程语言的一个特点,最有名的是在C语言中。[1]在这些语言中,为了简化标准,并给予实现一定的灵活性,标准特别地规定某些操作的结果是未定义的,这意味着程序员不能预测会发生什么事。

例如,在C语言中,在任何自动变量初始化之前使用这个变量会产生未定义行为,除以零或访问数组定义的界限之外的元素(参见缓冲区溢出)也会产生未定义行为。在一般情况下,之后的任何行为是不确定的。特别是,标准从来没有要求编译器判断未定义行为,因此,如果程序调用未定义行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。


C和C++的未定义行为的一些例子[编辑]

尝试修改字符串字面量会产生未定义行为:[2]

char * p = "wikipedia"; // C++11中错误,C++98/C++03不推荐使用
p[0] = 'W'; // 未定义行为

防止这一点的方法之一是将它定义为数组而不是指针

char p[] = "wikipedia"; /* 正确 */
p[0] = 'W';

在C++可以使用标准模板库中的string类型,如下所示:

std::string s = "wikipedia"; /* 正确 */
s[0] = 'W';

除以零会导致未定义行为。根据 IEEE 754,float、double和long double类型的值除以零的结果是无穷大或NaN[3]

return x/0; // 未定义行为

某些指针操作可能导致未定义行为:[4]

int arr[4] = {0, 1, 2, 3};
int* p = arr + 5;  // 未定义行为

到达返回数值的函数(除main函数以外)的结尾,而没有一个return语句,会导致未定义行为:

int f()
{
}  /* 未定义行为 */

C程序设计语言》在第2.12节引用下面的代码作为未定义行为的例子:

printf("%d %d\n", ++n, power(2, n));    /* 未定义行为 */

以及

a[i] = i++; /* 未定义行为 */

参考资料[编辑]

  1. ^ Lattner, Chris. What Every C Programmer Should Know About Undefined Behavior. LLVM Project Blog. LLVM.org. May 13, 2011 [May 24, 2011]. 
  2. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §2.13.4 String literals [lex.string] para. 2
  3. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.6 Multiplicative operators [expr.mul] para. 4
  4. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.7 Additive operators [expr.add] para. 5

外部链接[编辑]

  • The Jargon File on "nasal demons," one possible consequence of undefined behavior