c++ - 在 C++ 函数调用中使用自增运算符是否合法?

标签 c++ function standards

this question 中发生了一些争论。关于以下代码是否合法的C++:

std::list<item*>::iterator i = items.begin();
while (i != items.end())
{
    bool isActive = (*i)->update();
    if (!isActive)
    {
        items.erase(i++);  // *** Is this undefined behavior? ***
    }
    else
    {
        other_code_involving(*i);
        ++i;
    }
}

这里的问题是 erase() 将使有问题的迭代器无效。如果在评估 i++ 之前发生这种情况,那么像这样递增 i 在技术上是未定义的行为,即使它看起来可以与特定的编译器一起使用。争论的一方说,在调用函数之前,所有函数参数都已被完全评估。另一方说,“唯一的保证是 i++ 将在下一条语句之前和使用 i++ 之后发生。无论是在调用 erase(i++) 之前还是之后,都取决于编译器。”

我提出这个问题是为了解决这场争论。

最佳答案

关于C++ standard 1.9.16:

When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. (Note: Value computations and side effects associated with the different argument expressions are unsequenced.)

所以在我看来,这段代码:

foo(i++);

完全合法。它将递增 i,然后使用 i 的先前值调用 foo。但是,这段代码:

foo(i++, i++);

产生未定义的行为,因为第 1.9.16 段还说:

If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

关于c++ - 在 C++ 函数调用中使用自增运算符是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/598148/

相关文章:

未安装 VS 的 Windows 系统上无法运行 C++ 程序 "VCRUNTIME140.dll was not found"

python - 使用文本文档更改列表中的项目

c - 在标准 C 中声明固定大小的整数 typedef

C++ 序列化消息的方法?

c++将函数参数(带有模板变量的结构)转换为函数体内的字符串

c++ - 迭代循环和 lambda 函数

javascript - 在 typescript 中扩展方法

javascript - JavaScript 中的函数如何被视为变量?

c# - 当 TryXxxx 方法返回 false 时,out 参数的标准行为是什么?

c++ - 根据 C/C++ 标准, "'“与 "\' 相同”吗?