C++ 某些未定义的行为是否比其他行为更未定义?

C++ 某些未定义的行为是否比其他行为更未定义?,c++,undefined-behavior,C++,Undefined Behavior,我的意思是:I+++I++是未定义的,因此对数组的越界写入也是如此 越界数组写入的不确定性是可以理解的:它可能被利用来运行任意代码,这是您可以得到的最不确定的。让我们称之为运行时未定义行为 然而,对于i+++i++,情况似乎有所不同。假设编译器生成了一些东西。具体是什么还没有定义。非常不明确。事实上,它是如此的不明确,以至于我们过去常常听到猫会怀孕(尽管最近——我认为,从2016年CppCon开始——人们开始意识到,不明确的行为毕竟不能让猫怀孕) 然而,一旦我们打开这个框,看到编译器生成了什么,

我的意思是:
I+++I++
是未定义的,因此对数组的越界写入也是如此

越界数组写入的不确定性是可以理解的:它可能被利用来运行任意代码,这是您可以得到的最不确定的。让我们称之为运行时未定义行为

然而,对于
i+++i++
,情况似乎有所不同。假设编译器生成了一些东西。具体是什么还没有定义。非常不明确。事实上,它是如此的不明确,以至于我们过去常常听到猫会怀孕(尽管最近——我认为,从2016年CppCon开始——人们开始意识到,不明确的行为毕竟不能让猫怀孕)


然而,一旦我们打开这个框,看到编译器生成了什么,并且它不是可利用的代码(注入、数据竞争等-例如,编译器选择将
i+++i++
全部扔掉),这不正是将要执行的吗?从那时起,它不是完美地定义了吗

换句话说,最后一种情况就是我们所说的编译时未定义行为。在cat术语中,它类似于,在打开框(参见生成的程序集)之前,其状态是未知的,此时您可以看到要执行的实际情况。(我想知道不明确的行为是否会让中毒的死猫怀孕。)

当然,未定义的行为是标准的法律术语。问题是关于现实中发生的“行为”。

“未定义的行为”是一个适用于标准的术语。如果标准说行为是未定义的(或者没有直接或间接地定义),那么标准的实施可能会采取其作者希望的任何行动——或者任由事情自行发展,如果命运决定,就会导致一窝小猫。从标准的角度来看,这是一个二进制定义/未定义,没有“更多”或“更少”定义

现在,除了标准,你还有现实:

所以-如果标准未定义行为,那么智能、友好的编译器将生成错误或警告(或运行时错误和编译时警告)。允许这样做;毕竟,没有什么能阻止这种反应

一个稍微不那么友好和聪明,但仍然相当友好和聪明的编译器将尝试创建一个危害最小的代码。比方说,如果您没有初始化指针,它仍然会将其初始化为最有意义的值,无论是nullptr,还是给定类的唯一实例,指针的类型,等等。这并不是很聪明,因为它掩盖了bug,比如说,如果您切换到不同的编译器,或者行为变得标准化,或者使用编译器之外的其他东西,或者违背您的意图,这些bug可能会咬到您。不过,这是一种方法,并不违法。一些更高级的语言,如Javascript,倾向于这样做,试图真正理解错误代码

此外,如果这种反应确实有意义并且“挽救了一天”,那么在99.999%的情况下,做作者想做的事——其他作者也可能开始实施它(即使只是作为警告消息中的修复提示),它最终可能会进入标准

最后但并非最不重要的是,编译器将应用适用于单独部分的语法规则,并生成一些可能没有多大意义的东西。这不太可能产生小猫,而且你绝对不能保证结果是可重复的——但通常是可重复的。比方说,在指针上调用“delete”来指向不是用“new”创建的内容,这将导致分段错误。但这是“唯一”的做法,没有任何保证

你不太可能真的遇到这样的软件,它会不厌其烦地导致与未定义的行为毫无关联的结果,所以暂时不要给你的猫喷香水,但标准并没有禁止这样做。如果你的软件的作者有一种扭曲的幽默感,你可能会面临更具创造性的东西。与Unix上的PAM系统类似,当遇到缺少passwd文件(所有用户帐户定义)时,登录时会告诉您“您不存在。走开。”

“未定义的行为”是一个适用于标准的术语。如果标准说行为是未定义的(或者没有直接或间接地定义),那么标准的实施可能会采取其作者希望的任何行动——或者任由事情自行发展,如果命运决定,就会导致一窝小猫。从标准的角度来看,这是一个二进制定义/未定义,没有“更多”或“更少”定义

现在,除了标准,你还有现实:

所以-如果标准未定义行为,那么智能、友好的编译器将生成错误或警告(或运行时错误和编译时警告)。允许这样做;毕竟,没有什么能阻止这种反应

一个稍微不那么友好和聪明,但仍然相当友好和聪明的编译器将尝试创建一个危害最小的代码。比方说,如果您没有初始化指针,它仍然会将其初始化为最有意义的值,无论是nullptr,还是给定类的唯一实例,指针的类型,等等。这并不是很聪明,因为它掩盖了bug,比如说,如果您切换到不同的编译器,或者行为变得标准化,或者使用编译器之外的其他东西,或者违背您的意图,这些bug可能会咬到您。不过,这是一种方法,并不违法。一些更高级的语言,如Javascript,倾向于这样做,试图真正理解错误代码

此外,如果这种反应确实有意义并且“挽救了一天”,那么在99.999%的情况下,做作者想做的事——其他作者也可能开始实施它(即使只是作为警告消息中的修复提示),它最终可能会进入标准

最后但并非最不重要的是,编译器将