发布网友 发布时间:2024-02-22 17:38
共2个回答
热心网友 时间:2024-04-09 04:01
就是说,你用到了某一个变量,但是没有定义,这样的行为一般都是错误的,编译器即使通过,也很有可能发生错误热心网友 时间:2024-04-09 03:59
使用未定义的变量只是所有未定义行为中最简单的一种,是编译器特别容易发现的一个错误。引用楼主说的一句话:
未定义行为源于编译器不能检测到的程序错误或太麻烦以致无法检测到的错误。
如果未定义行为真的只是使用了未定义的变量的值,怎么可能会有不能检测到的情况。
制定C++语言标准的那些人对于一些情况没有定义应该按照什么样的顺序去进行计算,那么实现编译器的那伙人在处理这种问题上就会存在分歧,如何处理都不算错,那么对于使用编译器的人来说无法预估一个语句的执行顺序,自然就有可能会存在不同的执行结果。
int i = 0; i = i++;对于上面两句代码,执行后i的值是多少,先赋值后自增结果为1,先自增后赋值的情况下,因为赋值的是自增前的值,所以结果为0,我在gcc和VS2012中测试的结果确实是不同的。
假设你期望上面这段语句的执行结果为1,你在你自己的环境里测试结果也确实是1,那么你认为这段语句是正确的,并且继续使用了这段代码,以后换了一个环境就可能会出错。这就叫做“依赖了未定义的行为,即使程序能运行也是巧合”。实际上我们应该杜绝依赖巧合编程。
int a = g() * h() + i() * j();这是第二个例子,因为我并没有说明这几个函数内部是否使用或改变了全局变量,如果确实使用了那这就又是一个典型的未定义行为。
因为在制定C++语言标准的时候,同样没有定义这种语句的执行顺序,你不知道这四个函数的调用顺序是怎样的,一般来讲问题不大,但确实有极低的概率会造成未定义行为。
int arr[10], i;永远不要读写数组以外的空间,就比如上面这段代码,由于把<写成了<=,i是有可能等于10的,那么就相当于给数组外的空间赋值了。
再看上面的定义,i正好在arr[10]的后面,如果i的地址正好和arr[10]紧挨着呢,那么上面的这段代码就成了死循环。
C++标准未定义某些行为的执行细节,是为了让不同的编译器厂商放开手脚,尽情优化,所以造成了不同编译器的处理细节不同。
但是对于我们来讲则应该杜绝使用未定义行为,不要依赖巧合编程。