【问题标题】:Undefined Behavior when using Comma Operator in C++在 C++ 中使用逗号运算符时的未定义行为
【发布时间】:2021-11-17 14:54:00
【问题描述】:

我正在尝试学习如何在 C++ 中评估表达式。所以尝试和阅读不同的例子。下面是我无法理解它是否会产生未定义行为的代码。代码来自here。所以我想既然他们用过,这一定不是UB。但我有疑问。

#include <iostream>
int main()
{
    int n = 1;
    //std::cout << n << " " << ++n << std::endl;//this is undefined behavior i am sure
    int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);//will this also produce UB because here also we have cout in the same manner as above?
    std::cout << "m = " << (++m, m) << '\n';
}

正如您在上面的代码中看到的,我确信声明:

cout << n << " " << ++n << endl;

产生未定义的行为。 我的问题是:

  1. 但是在逗号运算符中使用的相同语句会产生 UB(如上面的代码所示)吗?也就是说,下面给出的语句会产生 UB。
int m = (++n, std::cout << "n = " << n << '\n', ++n, 2*n);
  1. 我们如何解释上述语句的行为在前序、未排序等方面发生了什么。

PS:我知道从 C++11 开始,我们使用序列之前等而不是序列点,所以我为什么要根据当前标准进行解释。

【问题讨论】:

  • 这些都不是 C++17 及更高版本中的 UB。
  • 通过您的编辑,您现在总共提出了 3 个问题。请注意,我的答案针对的是 1 和 2,但不是您 PS 中的答案。请每个问题只回答一个问题,并且在收到答案后尽量不要更改问题来询问其他问题。
  • 你没有使用std::cout &lt;&lt; n &lt;&lt; " " &lt;&lt; ++n;“在逗号操作符内”。
  • 我只在我的问题中添加了一个陈述,因为我认为它会澄清我在问什么。我现在才注意到,在我最初错过的命令运算符中'\n' 之后有一个逗号。既然我已经看到了我错过的逗号,一切都变得有意义了。

标签: c++ c++11 c++17 undefined-behavior expression-evaluation


【解决方案1】:

来自cppreference的同一页面:

在逗号表达式E1, E2 中,表达式 E1 被求值,其结果被丢弃(尽管如果它具有类类型,它直到包含完整表达式的末尾才会被销毁),及其副作用在表达式 E2 开始计算之前完成(请注意,用户定义的 operator, 不能保证排序)(直到 C++17)。

由于代码中的逗号操作符是内置的,++nstd::cout &lt;&lt; "n = " &lt;&lt; n &lt;&lt; '\n' 和其他表达式之间的顺序是明确定义的。没有未定义的行为。

因为您可能已经阅读了以上内容,所以这里是wording from the standard

一对用逗号分隔的表达式从左到右计算;左表达式是丢弃值表达式。 左表达式在右表达式之前排序([intro.execution])。

【讨论】:

  • 您的第一个报价可能会遗漏格式中的重要信息。在句子中'a user-defined operator, cannotGuaranteesequence'部分'operator'是一个函数名,所以它应该是代码样式。
  • @CianPan 格式与原始报价相同。
  • @CianPan 不太好,突出显示“直到 C++17”,但是操作符,不使用代码格式
  • @CianPan 谢谢我没能在浏览器中检查源代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 2018-03-30
  • 1970-01-01
  • 2017-07-11
  • 2010-12-16
  • 2017-01-13
  • 2013-05-19
相关资源
最近更新 更多