C的未指定、未定义和实现定义的行为WIKI

C的未指定、未定义和实现定义的行为WIKI,c,undefined-behavior,unspecified-behavior,C,Undefined Behavior,Unspecified Behavior,尽管有很多关于这个主题的链接,但我认为缺少了一些东西:用通俗易懂的语言清楚地解释未指定行为(UsB)、未定义行为(UB)和实现定义行为(IDB)之间的区别详细但简单地解释任何用例和示例 注意:为了简洁起见,我在这个WIKI中创建了UsB首字母缩略词,但不希望在其他地方看到它 P>我知道这可能是其他帖子的复制品(更贴近它),但很强,在有人把它标记为复制< >之前,请考虑我已经找到的所有材料的问题(我将从这篇文章中制作一个社区wiki): 太多零散的例子。当然,例子并不坏,但有时你找不到一个能

尽管有很多关于这个主题的链接,但我认为缺少了一些东西:用通俗易懂的语言清楚地解释未指定行为(UsB)、未定义行为(UB)和实现定义行为(IDB)之间的区别详细但简单地解释任何用例和示例

注意:为了简洁起见,我在这个WIKI中创建了UsB首字母缩略词,但不希望在其他地方看到它

<> P>我知道这可能是其他帖子的复制品(更贴近它),但<>很强,在有人把它标记为复制< <强> >之前,请考虑我已经找到的所有材料的问题(我将从这篇文章中制作一个社区wiki):

  • 太多零散的例子。当然,例子并不坏,但有时你找不到一个能很好地解决他手头问题的例子,所以它们可能会让人困惑(尤其是新手)

  • 示例通常只是一些解释很少的代码。在这些微妙的问题上,尤其是对于(相对的)新手来说,自上而下的方法可能会更好:首先是一个清晰、简单的解释和一个抽象的(但不是法律的)描述,然后是一些简单的例子,解释它们为什么会触发某些行为

  • 有些帖子经常使用C和C++的例子。C和C++有时不一致,他们认为USB,UB和IDB,因此一个例子可能会误导一些不精通两种语言。< /P>
  • 当给出UsB、UB和IDB的定义时,通常是对标准的简单引用,有时可能不清楚或对新手来说太难理解

  • 有时引用的标准是局部的。许多帖子只引用对当前问题有用的部分的标准,这很好,但缺乏通用性。此外,标准的引用通常并没有任何解释(对初学者来说是不好的)

因为我自己不是这方面的超级专家,所以我将创建一个社区WIKI,这样任何感兴趣的人都可以贡献自己的力量并改进答案

为了不破坏我创建一个结构化的初学者友好型维基的目的,我希望海报在编辑维基时遵循几个简单的指导原则:

  • 对您的用例进行分类。尝试将您的示例/代码放在已经存在的类别下(如果适用),否则创建一个新的类别

  • 首先是简单的文字描述。首先用简单的文字描述(当然,不要过于简单化——质量第一!)你试图提出的例子或观点。然后放入代码样本或引用

  • 引用标准。不要发布各种标准的片段,但要给出明确的参考(例如C99 WG14/N…第1.4.7节,段落…),并尽可能发布相关资源的链接

  • 更喜欢免费的在线资源。如果你想引用书籍或非免费可用的资源,这没关系(可能会提高WIKI的质量),但也可以尝试添加一些免费资源的链接。这一点非常重要,尤其是对于ISO标准而言。欢迎您添加到官方标准的链接,但也可以尝试添加到免费提供的草稿的等效链接。请不要用官方标准的参考取代草案的链接,添加到这些链接中。甚至一些大学的计算机科学系也没有ISO标准的副本,更不用说大多数程序员了

  • 除非真的有必要,否则不要发布代码。仅当仅使用简单英语的解释会令人尴尬或不清楚时,才发布代码。尝试将代码示例限制为一行。将链接发布到其他SO问答

  • <> > >不要发布C++实例。< /强>我希望这成为一种FAQ <强> > C<强>(如果有人想启动C++的双线,那就太棒了)。与C++相关的差异是受欢迎的,但只是作为侧记。这是在你彻底解释C案例之后,你可以添加一些关于C++的语句,如果这将帮助C程序员在切换到C++时,但是我不想看到更多的例子,比如说,20% C++的东西。通常一个简单的注释,比如“(C++在这种情况下的行为不同)”加上一个相关链接就足够了


因为我是个新手,所以我希望这样开始问答不会违反任何规则。如果是这样的话,我很抱歉。欢迎MOD让我知道这一点。

C标准定义UsB、UB和IDB的方式可以总结如下:

未指定行为(UsB) 这是一种行为,标准给出了一些备选方案,其中实施必须选择,但它不要求如何进行选择以及何时进行选择。换句话说,实现必须在不出错的情况下接受触发该行为的用户代码,并且必须符合标准给出的备选方案之一

请注意,实施不需要记录所做选择的任何内容。这些选择也可能是不确定的或依赖于编译器选项(以未记录的方式)

总而言之:该标准给出了一些选择的可能性,实现选择了选择和应用特定替代方案的时间和方式

请注意,该标准可能会提供大量的替代方案。典型的例子是未显式初始化的局部变量的初始值。标准规定,只要该值是变量数据类型的有效值,则该值未指定<
int const a = 42;
...
int* ap0 = &a;      //< error, compiler will tell us
int* ap1 = (int*)a; //< silences the compiler
...
*ap1 = 43;          //< UB ==> program crash?