编程中的“未定义行为”问题

在计算机程序设计中,未定义行为(undefined behavior)是指行为不可预测的计算机代码。(尤其是在c语言中中) 因为简化标准,所以标准规定某些操作是未定义的,意味着:程序员不能够预测会发生什么事情。 即为:(标准从来没有要求编译器判断未定义行为)可能会编译成功,甚至一开始运行就没有错误,但是可能在另外一个系统或者另外一个日期运行失败。———>”什么事情都可能发生,也许什么事情都没有发生“。

eg:(1)(c语言)在任何自动对象被初始化之前,通过非字符类型的左值表达式读取这个变量存储的值会产生未定义行为。 (2)除以0 (3)访问数据定义的界限之外的元素也会产生为定义行为。

和为指定行为(unspecified behavior)不同,未定义行为强调基于不可移植、错误的程序构造、使用错误的数据。

【一个符合标准的实现可以在假定未定义行为永远不发生的基础上优化,可能导致原本存在未定义行为的程序经过优化后显示出更加明显的错误(eg:死循环)】。————> 未定行为一般应被视为bug。

下面是未定义的例子: 1)尝试修改字符串字面量会产生未定义行为: char * p = “wikipedia”; // C++11中错误,C++98/C++03不推荐使用 p[0] = ‘W’; // 未定义行为 (好像一般是用数组来存储字符的时候(变成字符串),才会可以用户修改数组) 解决方案: (1)就是将它定义为数组而不是指针。 char p[] = “wikipedia”; p[0] = ‘W’ //这样就可以修改了 (2)C++ 中可以使用标准模板库中的string类: std::string s = “wikipedia”; s[0] = ‘W’

2)除以零会导致未定义行为 return x/0; //未定义行为

3)某些指针操作可能导致未定义行为: int arr[4] = {0,1,2,3}; int *p = arr + 5; //为定义行为

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

5)printf(“%d %d ”, ++n, power(2, n));//未定义行为

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

标准库可能制定未定行为,(下面的是格式控制和要输出的不一致) eg: int x = 1; printf(“%d ”,&x); //未定义行为,%d预期int类型的实际参数 printf(“%p ”,&x); //未定义行为,%p 预期void* 类型的实际参数 printf(“%p ”,(void*)&x); //%p 和 void* 类型的实际参数匹配,不在此引发未定义行为

经验分享 程序员 微信小程序 职场和发展