Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C和C+的差异+;具有序列点和UB 我用这个帖子来记录C程序中的未定义行为(UB),并指出我的代码< C和C++有自己的发散规则,用于[序列点] < /C>。那么C++和C++在序列点和相关的UB上有什么区别呢?我不能用一个关于C++序列的帖子来分析C代码中发生了什么吗?_C++_C_Language Lawyer_Undefined Behavior_Sequence Points - Fatal编程技术网

C和C+的差异+;具有序列点和UB 我用这个帖子来记录C程序中的未定义行为(UB),并指出我的代码< C和C++有自己的发散规则,用于[序列点] < /C>。那么C++和C++在序列点和相关的UB上有什么区别呢?我不能用一个关于C++序列的帖子来分析C代码中发生了什么吗?

C和C+的差异+;具有序列点和UB 我用这个帖子来记录C程序中的未定义行为(UB),并指出我的代码< C和C++有自己的发散规则,用于[序列点] < /C>。那么C++和C++在序列点和相关的UB上有什么区别呢?我不能用一个关于C++序列的帖子来分析C代码中发生了什么吗?,c++,c,language-lawyer,undefined-behavior,sequence-points,C++,C,Language Lawyer,Undefined Behavior,Sequence Points,*当然,我不是说C++的特性不适用于C这个问题有两个部分,我们可以轻松地比较序列点规则。这并没有使我们太远,C和C++是不同的语言,它们有不同的标准(几乎是两倍大),即使C++使用C作为标准参考,引用C的C++标准是错误的,反之亦然,不管某些部分是多么相似。C++标准明确地引用了C标准,但对于小的部分是这样的。 第二部分是C与C++的比较,可以有一些较大的差异,列举出所有未定义行为的差异可能是不可能的,但我们可以给出一些指示性的例子。 序列点 因为我们正在讨论的是C++11和C11之前的版本。就

*当然,我不是说
C++
的特性不适用于
C

这个问题有两个部分,我们可以轻松地比较序列点规则。这并没有使我们太远,C和C++是不同的语言,它们有不同的标准(几乎是两倍大),即使C++使用C作为标准参考,引用C的C++标准是错误的,反之亦然,不管某些部分是多么相似。C++标准明确地引用了C标准,但对于小的部分是这样的。 第二部分是C与C++的比较,可以有一些较大的差异,列举出所有未定义行为的差异可能是不可能的,但我们可以给出一些指示性的例子。 序列点

因为我们正在讨论的是C++11和C11之前的版本。就我所知,C99和C++11之前的草案标准之间的序列点规则没有太大差异。正如我们将在我给出的一些不同未定义行为的示例中看到的,序列点规则在其中不起作用

序列点规则在
1.9
程序执行一节中介绍,其中说明:

  • 每个完整表达式的评估完成时有一个序列点12)
  • 调用函数时(无论函数是否为内联函数),在对所有函数求值之后都有一个序列点 在执行函数体中的任何表达式或语句之前发生的函数参数(如果有)
  • 在复制返回值之后和执行外部任何表达式之前,还有一个序列点 功能(13)。C++中的几个上下文导致函数调用的评估,即使没有相应的函数调用。 语法出现在翻译单元中。[示例:对新表达式的求值调用一个或多个分配和 构造函数;参见5.3.4。另一个例子是,在上下文中可能会调用转换函数(12.3.2) 其中没有出现函数调用语法。-结束示例]序列指向函数入口和函数出口 (如上所述)是经过计算的函数调用的特性,无论调用 功能可能是
  • 在计算每个表达式时

    a && b
    a || b
    a ? b : c
    a , b
    
    使用这些表达式(5.14、5.15、5.16、5.18)中运算符的内置含义,后面有一个序列点 第一个表达式的评估14)

我将使用C99标准草案
附录C
中的序列点列表,虽然它不是规范性的,但我发现与它引用的规范性章节没有任何分歧。它说:

以下是5.1.2.3中描述的序列点:

  • 对参数求值后对函数的调用(6.5.2.2)
  • 以下运算符的第一个操作数的结尾:逻辑AND&&(6.5.13); 逻辑或(6.5.14);有条件的(6.5.15); 逗号,(6.5.17)
  • 完整声明符的结尾:声明符(6.7.5)
  • 完整表达式的结尾:初始值设定项(6.7.8);表达式中的表达式 声明(6.8.3);选择语句的控制表达式(if或switch) (6.8.4); while或do语句的控制表达式(6.8.5);每个 声明的表述(6.8.5.3);返回语句中的表达式 (6.8.6.4)

以下条目在C++标准草案中似乎没有等价物,但这些来自C标准库,C++中引用了:

  • 在库函数返回之前(7.1.4)
  • 与每个格式化输入/输出函数转换关联的操作之后 说明符(7.19.6、7.24.2)
  • 在每次调用比较函数之前和之后,以及 在对比较函数的任何调用和对象的任何移动之间 作为参数传递给该调用(7.20.5)
因此,C和C++之间的差别不大。

未定义的行为

当涉及到序列点和未定义行为的典型示例时,例如
5
Expression一节中涉及的那些在序列点内多次修改变量的示例,我无法给出一个未定义但另一个未定义的示例。C99中说:

在上一个序列点和下一个序列点之间,对象应具有 通过计算 表达式72)此外,先前值应仅读取至 确定要存储的值。73)

它提供了以下示例:

i = ++i + 1;
a[i++] = i;
i = v[i ++]; / / the behavior is undefined
i = ++ i + 1; / / the behavior is undefined
在C++中,它表示:

除非另有说明,否则单个操作数的计算顺序 单个表达式的运算符和子表达式,以及顺序 在哪种情况下会产生副作用,目前尚不清楚 上一个和下一个序列点应存储标量对象的 通过表达式求值最多修改一次的值。 此外,只能通过访问先验值来确定 要存储的值。应满足本段的要求 对于完整表达式的子表达式的每个允许顺序 表达方式;否则,行为是未定义的

并提供以下示例:

i = ++i + 1;
a[i++] = i;
i = v[i ++]; / / the behavior is undefined
i = ++ i + 1; / / the behavior is undefined
在C++11和C11中,我们有一个主要的区别