< C和C++中的未定义行为是什么?那么未指定的行为和实现定义的行为呢?他们之间有什么区别
让我们看一个经典的例子:
#包括<;iostream>;
int main()
{
char*p=";hello!\n";//是的,我知道,不推荐的转换
p[0]=“y”;
p[5]=‘w’;
标准::cout<;<;p;
}
变量p指向字符串literal";你好!\",下面的两个赋值尝试修改该字符串文字。这个程序做什么?根据C++标准第2.14节第11段,调用未定义行为:
试图修改字符串文字的效果未定义
我能听到人们的尖叫声;但是等等,我可以毫无问题地编译它,并获得输出;或;什么意思?未定义的字符串文本存储在只读内存中,因此第一次分配尝试会导致核心转储;。这正是未定义行为的问题所在。基本上,该标准允许在调用未定义的行为(甚至鼻恶魔)后发生任何事情。如果有一个;“正确”;根据你的语言思维模式,这种模式是完全错误的;C++标准只有投票权,期限。
未定义行为的其他示例包括访问超出其边界的数组、取消对空指针的引用、在对象生命周期结束后访问对象或编写所谓的聪明表达式,如i+++++i
C++标准的第1.9节还提到了未定义行为的两个不太危险的兄弟,未指定的行为和实现定义的行为:
本国际标准中的语义描述定义了参数化的非确定性抽象机器
本国际标准将抽象机的某些方面和操作描述为实现定义的(例如,
sizeof(int))。这些构成了抽象机器的参数。每个实施应包括描述其在这些方面的特征和行为的文件本国际标准将抽象机的某些其他方面和操作描述为未指定的(例如,函数参数的求值顺序)。在可能的情况下,本国际标准定义了一组允许的行为。这些定义了抽象机器的不确定性方面
在本国际标准中,某些其他操作被描述为未定义的(例如,取消引用空指针的效果)。[注意事项:本国际标准对包含未定义行为的程序的行为没有任何要求。-结束注意事项]
具体而言,第1.3.24节规定:
允许的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行过程中以环境特有的文件化方式(无论是否发出诊断消息)进行行为,再到终止翻译或执行(发出诊断信息)
你能做些什么来避免陷入未定义的行为?基本上,你必须阅读那些知道他们在说什么的优秀的C++书籍。避免网络教程。避免Bull ScLydt。