9.3 不确定的行为
对于某些用法,ANSI/IS C++(www.cppentry.com)不会对C++(www.cppentry.com)实现的行为强加任何要求。例如,对于左移或者右移运算符(<<或者>>),如果右操作数是负的,或者右操作数大于或者等于左操作数的字节数,那么结果将会是不确定的。在构造函数中,调用构造对象的纯虚函数也会导致不确定的行为,除非使用了显式限定。
在C++(www.cppentry.com)语言定义中,大约有十几个结构具有未经定义的行为。根据C++(www.cppentry.com)标准,编译系统对这些包含有这些结构的程序的处理同时也是不确定的。例如,假设我们的程序是一个输入程序,那么编译器的处理行为将会是下面中的一种:
产生一个诊断信息;
中止;
删除文件系统所有的文件(虽然这种编译器早晚肯定会被淘汰);
既不产生错误消息,也不产生警告消息,生成可执行代码。
而且,如果编译系统生成了可执行代码,那么这份代码的行为可能如下:
产生程序员所希望的结果;
产生不正确的结果;
中止;
删除文件系统中所有的文件。
遗憾的是,当程序发生不确定行为的时候,很少有C++(www.cppentry.com)实现会通知程序员。如果旨在编写可移植的C++(www.cppentry.com)代码,那么你必须具有小心谨慎的态度,以便避免编写这样的结构。
对于可移植代码而言,一个要特别关注的领域是内存布局(memory layout)-主要指:对象的大小和排列方式、指针和地址操纵。许多C++(www.cppentry.com)程序员都把可执行程序的地址空间看作是连续的字节序列,设置为适当值的char*或void*的指针变量都可以取到这些地址。然而,平台不是唯一的,也存在不符合这种简单内存布局模式的平台;因此,对于依赖于这种布局模式的代码,对这些平台而言,就是不可移植的。