未定义、未指定和实现定义的行为 < C和C++中的未定义行为是什么?那么未指定的行为和实现定义的行为呢?它们之间的区别是什么?

未定义、未指定和实现定义的行为 < C和C++中的未定义行为是什么?那么未指定的行为和实现定义的行为呢?它们之间的区别是什么?,c++,c,undefined-behavior,unspecified-behavior,implementation-defined-behavior,C++,C,Undefined Behavior,Unspecified Behavior,Implementation Defined Behavior,嗯,这基本上是标准的直接复制粘贴 3.4.11实施定义的行为未指定的行为,其中 每一个实现都记录了 作出选择 例如:例句 实现定义的行为是 当 有符号整数右移 3.4.31未定义的行为使用不可移植或错误的 程序构造或错误的 数据,此国际 标准没有规定任何要求 二, 注意可能的未定义行为 范围从忽略情况 结果完全不可预测,, 翻译或翻译过程中的行为 以文档化的方式执行程序 行为举止 环境(带或不带 发出诊断信息),以 终止翻译或执行 (随着诊断报告的发布 信息) 例 undefined behav

嗯,这基本上是标准的直接复制粘贴

3.4.11实施定义的行为未指定的行为,其中 每一个实现都记录了 作出选择

例如:例句 实现定义的行为是 当 有符号整数右移

3.4.31未定义的行为使用不可移植或错误的 程序构造或错误的 数据,此国际 标准没有规定任何要求

二, 注意可能的未定义行为 范围从忽略情况 结果完全不可预测,, 翻译或翻译过程中的行为 以文档化的方式执行程序 行为举止 环境(带或不带 发出诊断信息),以 终止翻译或执行 (随着诊断报告的发布 信息)

例 undefined behavior是上的行为 整数溢出

3.4.41未指定行为使用未指定值或其他行为 这个国际标准在哪里 提供两种或两种以上的可能性和 没有对其提出进一步的要求 在任何情况下都可以选择

二, 示例未指定的示例 行为是行为发生的顺序 对函数的参数进行求值

有一个简短的描述

他们的最后总结:

总而言之,未指明的行为通常是你不应该做的 担心,除非你的软件需要是可移植的。 相反,未定义的行为总是不受欢迎的,永远不应该 发生


也许简单的措辞比严格的标准定义更容易理解

实现定义的行为
语言说我们有数据类型。编译器供应商指定了他们应该使用的大小,并提供了他们所做工作的文档

未定义的行为
你做错了什么。例如,在
int
中有一个非常大的值,它不适合
char
。如何将该值放入
char
?其实没有办法!任何事情都可能发生,但最明智的做法是获取int的第一个字节并将其放入
char
。分配第一个字节是错误的,但在引擎盖下就是这样

未指定的行为
这两个函数中的哪一个先执行

void fun(int n, int m);

int fun1() {
    std::cout << "fun1";
    return 1;
}
int fun2() {
    std::cout << "fun2";
    return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?
void fun(int n,int m);
int fun1(){
STD::CUT< P> <强>未定义行为< /强>是C语言和C++语言的一个方面,对来自其他语言的程序员来说是令人惊讶的(其他语言试图更好地隐藏它)基本上,可以编写C++程序,这些程序的行为不可预测,即使许多C++编译器不会报告程序中的任何错误!
让我们看一个经典的例子:

#include <iostream>

int main()
{
    char* p = "hello!\n";   // yes I know, deprecated conversion
    p[0] = 'y';
    p[5] = 'w';
    std::cout << p;
}
#包括
int main()
{
char*p=“hello!\n”;//是的,我知道,不推荐的转换
p[0]=“y”;
p[5]=‘w’;

标准::cout来自官方的C基本原理文件

术语“未指定的行为”、“未定义的行为”和“实现定义的行为”用于对编写程序的结果进行分类,这些程序的属性标准没有或不能完全描述。采用这种分类的目的是允许实现之间存在一定的差异,从而保证实现的质量n成为市场上的一支积极力量,并允许某些流行的扩展,而不消除符合标准的标志。标准附录F列出了属于这三类行为之一的行为

未指定的行为为实现者翻译程序提供了一定的自由度。该自由度不会延伸到无法翻译程序的程度

未定义行为允许实现者不捕获某些难以诊断的程序错误。它还确定了可能的一致性语言扩展区域:实现者可以通过提供官方未定义行为的定义来扩充语言

实现定义的行为使实现者可以自由选择适当的方法,但需要向用户解释此选择。指定为实现定义的行为通常是指用户可以根据实现定义做出有意义的编码决策的行为。实现者应承担在决定实现定义应该有多广泛时,请记住这个标准。与未指定的行为一样,简单地不翻译包含实现定义行为的源代码并不是一个适当的响应


C++标准n3337§1.3.10 实现定义的行为

行为,对于格式良好的程序构造和正确的数据 取决于执行情况和每个执行文件

有时候,C++标准不在某些结构上施加特定行为,而是说,特定的、明确的行为必须被选择,并且<>强> >特定的实现(库的版本)。因此,即使标准没有描述,用户仍然可以准确地知道程序的行为。

C++标准n3337§1.3.24 未定义的行为

本国际标准不要求的行为 [注:当发生这种情况时,可能会出现未定义的行为 标准省略了任何解释
int scaled_velocity(int v, unsigned char pow)
{
  if (v > 250)
    v = 250;
  if (v < -250)
    v = -250;
  return v << pow;
}