【问题标题】:Undefined behavior in C [duplicate]C中未定义的行为[重复]
【发布时间】:2021-05-14 03:16:55
【问题描述】:

this 网站的最后一节中,他们提供了f(i = -1, i = -1) 作为未定义行为的示例,原因是函数参数中子表达式的评估未排序。但是由于在所有函数参数和函数指示符的求值之后和实际函数调用之前都有一个序列点f 将始终使用(-1, -1) 调用,而i 将被分配-1。有没有可能不发生这种情况?

【问题讨论】:

  • 也许函数会改变i(全局变量?)
  • 也许,但它仍然不会被定义为行为吗?因为最后我将“肯定”在“f”内分配值而不是-1。
  • 要明确一点:函数调用中的逗号不是是一个序列点。函数参数求值顺序未指定,所以这确实是UB。
  • 链接的答案有一个(稍微做作的)可能出错的示例。
  • @dratenik 鉴于当今的高度流水线 CPU 实际上确实并行执行多个指令,我不会说这个例子是在任何人为设计的方式。

标签: c undefined-behavior sequence-points


【解决方案1】:

...求值后有一个序列点

的确如此。 经过评价,所以不好。这里的问题是在i before 序列点上有两个未排序的副作用。它是正式的 UB。

【讨论】:

  • 如果给 i 分配了不同的值,那么它将是未定义的,因为 i 的值无法预见......但在这种情况下,我总是会评估为 -1.. 不是它
  • @SouravKannanthaB 不,值无关紧要。假设我们有一些奇特的场景,其中i 是一个易失性硬件寄存器,每次写入它都会在硬件中发生一些事情。这段代码是否、何时或多少次写入该硬件寄存器并没有明确定义。
  • @SouravKannanthaB 在一个更现实的例子中,比如主流 x86 PC 编译器,它可能会尝试做一些看似有用的事情,并且很可能只是传递值 -1。但是没有任何特定行为的保证,只是超出 C 语言范围的实现质量问题。
【解决方案2】:

这是未定义的行为,因为标准说明了这一点。修改修改之间没有序列点的变量是UB。该规则没有“除非两个修改设置相同的值”例外。

【讨论】:

  • 所以你的意思是“使用这个特定的值”这可能会导致预期的行为,但是具有两个不同值的类似表达式会导致未定义的行为。当然...
  • @SouravKannanthaB 不,这意味着:“规则没有 [...] 例外。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 2017-02-15
  • 2018-01-06
  • 2014-11-21
相关资源
最近更新 更多