未定义行为是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果;或者程序调用未定义行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至在另一个日期运行失败。
当一个未定义行为的实例发生时,“什么事情都可能发生”,也许什么都没有发生。
未定义行为就是运行结果不确定。
eg:
1、一个变量即是左边的结果,又是右边的操作数,如a+=a++,a%=b^=a^=b^=a
2、使用越界数组也是C的一个“未定义行为”
3、允许一个随便指的指针的读写
4、使用未初始化的变量
下面C代码中,不属于未定义行为的是:C
A、int i=0; i=(i++);
B、char *p="hello";p[1]='E';
C、char *p="hello";char ch=*p++;
D、int i=0;printf("%d%d\n",i++,i--);
E、都是未定义行为
F、都不是未定义行为
解析:
A在GCC下输出0,在VC6.0中输出1;
B在GCC下输出段错误(核心已转储),在VC6.0下输出会停止工作,出现问题,导致程序停止正常工作。(常量字符串不允许修改,因为放在常量区,一修改就错)
C正常;(C修改的是指针的值,没有修改指针指向常量的值。)
D在GCC下输出-1、0;在BC6.0下输出0、0;
补充:不要依赖未定义行为。
C++中的未定义行为有:
1、连接字符串字面值和宽字符串字面值。
2、使用在函数体内定义的未初始化的变量。
3、获取不存在的元素也是未定义行为。例如:数组、string、vector等通过下标操作符获取超过该对象的长度元素。
所谓的“缓冲区溢出”问题就是对不存在的元素进行下标操作的结果。这样的缺陷往往导致PC机和其他应用中最常见的安全问题。
4、若造成非有2个以上的操作数,则求这两个操作数的值的顺序未定义。