设为首页 加入收藏

TOP

6.1.3 未指定的行为
2013-10-06 23:55:08 来源: 作者: 【 】 浏览:49
Tags:6.1.3 指定 行为
6.1.3 未指定的行为
它涵盖了这样一种情况:编译器可以自由选择任意一种合理的动作,实现工具也不需要在 文档中说明编译器将选择哪一种动作。这很常见,因为所有可能的选择通常将拥有完全相同的 结果。然而,这常常可能会导致构建出这样的代码:其行为随着编译器做出不同的选择而发生 变化。
未指定的行为的一个例子是C++(www.cppentry.com)(与像Java这样的某些别的语言不同)不指定子表达式 (subexpressions)(更大的表达式的组成部分)的求值顺序。考察以下源代码:
C++(www.cppentry.com)标准要求按某种顺序调用add1_to_global()和add2_to_global()(即不能并行地将两个调 用发送给两个不同的CPU处理),但它没有指定先求解哪个表达式。在这种情况下,结果将依 赖于编译器做出的选择。如果它按从左到右的顺序调用两个函数,则结果为4,但如果它以相 反的顺序调用它们,则结果为5。无论编译器做何选择,最终存储在global中的值都将是3。
因为C++(www.cppentry.com)标准未指定子表达式(本例中是两个函数调用)的求值顺序,所以4和5均是上述 程序的正确输出。实际上,你正在使用的编译器(假定你我所用为同一版本)将生成一个输出 为5的程序。这表明,编译器创建的代码先调用add2_to_global()而后调用add1_to_global()。(译 注:译者使用CD提供的MDS所得结果为4)
警告!
如果你还不知道全局变量可能引起严重的问题,那么这个例子应当向你示范 了优秀的程序员避开它们的原因之一。
尽管C++(www.cppentry.com)为“在表达式求值期间操作符的应用顺序”提供了规则,但它仅为子表达式的求 值顺序规定了极少的要求:对子表达式的求解,发生在操作符需要该子表达式的值之前。许多 程序员忽视了这条规则的完整含意。比方说,使用上述函数,
也具有未指定的行为。输出可以是“13”或“23”,这依赖于按什么顺序调用这两个函数。 此外,子表达式(在本例中是函数调用)的求值顺序可能会随着使用地点的不同而发生变化。
警告!
对子表达式的求值顺序做任何假定都是不安全的。运行测试代码也不会告诉 你任何更多的信息,因为你知道的只是这些子表达式在该测试代码中的求值顺序 而已。如果顺序很重要,你必须设法强制顺序,比方说将求值放到分开的语句中。 例如,
必定导致输出“13”,因为不存在重排整个语句的执行顺序的自由。
【责任编辑:雪花 TEL:(010)68476606-8007】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇6.1.2 由实现定义的行为 下一篇6.1.4 未定义的行为

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: