在C ++函数调用中使用increment运算符是否合法? [英] Is it legal to use the increment operator in a C++ function call?

查看:1235
本文介绍了在C ++函数调用中使用increment运算符是否合法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题关于以下代码是否合法C ++:

  std :: list< item * > :: iterator i = items.begin(); 
while(i!= items.end())
{
bool isActive =(* i) - > update
if(!isActive)
{
items.erase(i ++); // ***这是未定义的行为吗? ***
}
else
{
other_code_involving(* i);
++ i;
}
}

这里的问题是 erase()将使有问题的迭代器失效。如果在 i ++ 被评估之前发生这种情况,那么增量 i 就像这是技术上未定义的行为,即使它似乎工作与特定的编译器。辩论的一方面说,在调用函数之前,所有的函数参数都被完全求值。另一方面说,唯一的保证是i ++将在下一个语句之前和i ++之后发生,无论是在擦除之前(i ++)被调用还是后面是编译器依赖。



我打开这个问题,希望能够解决这个争论。

解决方案 //www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf\">C++ standard 1.9.16:



< blockquote>

当调用函数(无论是
还是函数不是内联函数)时,每个
值计算和副作用
与任何参数相关联
表达式,或者带有指定调用的
函数的postfix
表达式,在调用的
函数体内的每个表达式或
语句的
执行之前排序。 (注意:价值计算
和与
不同参数表达式相关的副作用是
无效的。)


所以对我来说,这段代码:

  foo(i ++) 

完全合法。它将增加 i ,然后调用 foo 与上一个值 i 。但是,此代码:

  foo(i ++,i ++) 

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


如果对标量对象的副作用是
,相对于另一个
,对同一个标量对象的副作用
或使用相同标量对象的值

行为未定义。



There's been some debate going on in this question about whether the following code is legal 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;
    }
}

The problem here is that erase() will invalidate the iterator in question. If that happens before i++ is evaluated, then incrementing i like that is technically undefined behavior, even if it appears to work with a particular compiler. One side of the debate says that all function arguments are fully evaluated before the function is called. The other side says, "the only guarantees are that i++ will happen before the next statement and after i++ is used. Whether that is before erase(i++) is invoked or afterwards is compiler dependent."

I opened this question to hopefully settle that debate.

解决方案

Quoth the 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.)

So it would seem to me that this code:

foo(i++);

is perfectly legal. It will increment i and then call foo with the previous value of i. However, this code:

foo(i++, i++);

yields undefined behavior because paragraph 1.9.16 also says:

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 ++函数调用中使用increment运算符是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆