【问题标题】:Undefined or unspecified behaviour?未定义或未指定的行为?
【发布时间】:2017-12-27 17:50:57
【问题描述】:

我正在阅读this article,他们使用以下示例来解释未定义的行为:

// PROGRAM 1
#include <stdio.h>
int f1() { printf ("Geeks"); return 1;}
int f2() { printf ("forGeeks"); return 1;}
int main() 
{ 
  int p = f1() + f2();  
  return 0; 
}

但是,这似乎与评估子表达式的顺序有关,并且根据 C 标准(附件 J.1),这是未指定的行为,而不是未定义的行为:

未指定的行为:评估子表达式的顺序和副作用的顺序 发生,除非为函数调用 () , &&, || 指定, ? : 和逗号 运营商 (6.5)

由于我对阅读官方规范非常陌生,我想知道我是否误解了示例或文档。我知道这可能看起来很迂腐,但我有兴趣以正确的方式学习这些高级主题。

【问题讨论】:

  • 解释未定义行为的示例”:显示的代码调用“未定义的行为”。
  • @parallelhighway:错了。正如 OP 所假设的,它明确是未指定,而不是未定义的行为。
  • 这个短语是不正确的,根据@Olaf 的说法:“程序 1 中未定义行为的原因是,运算符 '+' 对其操作数没有标准定义的求值顺序。”跨度>
  • @Olaf 你是对的,我在文章中也感到困惑。这篇文章混淆了这些术语。
  • @parallelhighway:维基百科是一个糟糕的标准解释资源。标准行为只有一种权威资源:标准。

标签: c language-lawyer standards


【解决方案1】:

您在问题中提供的链接给出了未定义行为的错误示例。 f1f2f1() + f2() 中的评估将是未指定的。请注意,标准说明了副作用以及评估顺序

计算子表达式的顺序和副作用发生的顺序 [...]

f1f2 评估中的副作用(输出到标准输出)不相关,它们不会导致任何未定义的行为。

这和下面的例子没有什么不同

int a = 1;
int b = 1, c;

c = a + b;

ab 的计算顺序未在表达式 a + b 中指定。

【讨论】:

  • 每个函数调用前后都有一个序列点,所以我认为你修改的程序也没有UB。
  • @zwol;是的。但是首先评估哪个函数?推荐阅读:Is f()+g() undefined or merely unspecified?
  • 只是未指定,就像在原版中一样。您的链接与我一致。
  • @zwol;我想我做错了。其实你是对的。
  • 写入标准输出是恕我直言的副作用,但 f1f2 中存在副作用的事实不会产生未定义的行为。
猜你喜欢
  • 2011-05-20
  • 2011-01-19
  • 2017-02-17
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多