C语言中的未定义行为
C语言的初学者经常会问一些貌似“专业”的问题,比如 #include <stdio.h> main() { int i = 5; int j = ++i+++i+++i;
printf("%d\n", j);
system("pause");
} 这样的问题实在不需要多做考虑,而且应该在实际编程实践中尽量避免。因为它们几乎都是“未指明的行为”或“由实现定义的行为”。另一方面,程序的错误或Bugs,通常是由于“未定义的行为”。 C++Primer第四版中的解释: 使用了未定义行为的程序都是错误的,即使程序能够运行,也只是巧合。未定义行为源于编译器不能检测到的程序错误或太麻烦以至无法检测的错误。 不幸的是,含有未定义行为的程序在有些环境或编译器中可以正确执行,但并不能保证同一程序在不同编译器中甚至在当前编译器的后继版本中会继续正确运行,也不能保证程序在一组输入上可以正确运行且在另一组输入上也能正确运行。 程序不应该依赖未定义行为。
未定义行为:没有定义那样做有什么意义的行为。
注意:不要依赖未定义行为。
c++中的未定义行为有:
1、连接字符串字面值和宽字符串字面值。
2、使用在函数体内定义的未初始化的变量(非用作赋值操作符的左操作数)。
3、获取不存在的元素也是未定义行为。例如:数组、string、vector等通过下标操作符获取超过该对象的长度的元素。
所谓的“缓冲区溢出”问题就是对不存在的元素进行下标操作的结果。这样的缺陷往往导致PC机和其他应用中最常见的安全问题。
4、若操作符有两个以上的操作数(例如a+b中,+有两个操作数),则求这两个操作数的值的顺序未定义(也就是说,先求a的值还是先求b的值是未确定的)。
上面这个未定义引出了下面的问题:
int a(11);
cout << a++ << a-- << a << endl;
该代码的输出结果未定义。