Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在同一表达式内使用表达式中的副作用结果安全吗?_C++_C_Language Lawyer - Fatal编程技术网

C++ 在同一表达式内使用表达式中的副作用结果安全吗?

C++ 在同一表达式内使用表达式中的副作用结果安全吗?,c++,c,language-lawyer,C++,C,Language Lawyer,考虑以下代码: int f(int a, int b, int *c) { *c = a + b; return *c > 0; } void check(int a, int b) { int c; if(f(a, b, &c) && c < 10) { puts("sum is in range [1, 9]"); } } intf(inta,intb,int*c){ *c=a+b; 返回*c>0

考虑以下代码:

int f(int a, int b, int *c) {
    *c = a + b;
    return *c > 0;
}

void check(int a, int b) {
    int c;
    if(f(a, b, &c) && c < 10) {
        puts("sum is in range [1, 9]");
    }
}
intf(inta,intb,int*c){
*c=a+b;
返回*c>0;
}
无效检查(内部a、内部b){
INTC;
如果(f(a、b和c)和c<10){
看跌期权(“总和在[1,9]范围内”);
}
}

如果曾经计算过
&&
的第二部分,是否保证
c
保存通过函数调用
f(a、b和c)
分配给它的值?这个行为是否从C变为C++?

< p>是的,表达式将从左到右进行计算,并且将相应地更新<代码> C <代码>的值。程序的执行将进入函数,函数中执行的任何内容都将在
c<10
之前执行


此行为不应从
C
更改为
C++

如果出现控制求值顺序的序列点,则是安全的

// bad: evaluation order of f() and (c < 10) is not specified by C
if(f(a, b, &c) & c < 10) {
// OK,  left half of && must occur first.
if(f(a, b, &c) && c < 10) {
//错误:c未指定f()和(c<10)的求值顺序
if(f(a,b和c)&c<10){
//好的,&&的左半部分必须先出现。
如果(f(a、b和c)和c<10){

使用简单的<代码> & & <代码>表达式,没有C,C++的区别。用C++来评估左侧,如果左边不是false,则对右边进行评价。 当C++中,<>代码> & & >代码>运算符可以重载,则总是对<代码>和的两侧进行评价。 是否保证

c
保存函数调用
f(a、b和c)

是的,这在[expr.log.and]中表达得非常清楚:


&&
运算符从左到右分组。操作数都在上下文中转换为
bool
(第4条)。 如果两个操作数都是
true
false
,则结果为
true
。与
&
不同,
&
保证从左到右 求值:如果第一个操作数为
false
,则不求值第二个操作数

如果对第二个表达式求值,则结果是一个
bool
,每个值的计算和副作用都是相关联的 第一个表达式在每次值计算和与之相关的副作用之前进行排序 第二个表达式。


&&
操作符强制从左向右求值,并引入一个序列点(函数调用本身也是如此);在决定是否需要求值RHS之前,将对LHS进行全面求值(并应用所有副作用)

因此,
如果(f(a,b,&c)和&c<10)
将按照您的预期工作;如果
c<10
被评估,它将使用函数
f
写入
c
的值

P.>已经说过,这不是很棒的风格。仅仅因为C和C++允许某些构造并不意味着使用它们是一个好主意。任何人都必须维护你的代码,你可能会感激你把它写为

if ( f( a, b, &c ) )
{
  if ( c < 10 )
  {
    // do stuff
  }
}
if(f(a、b和c))
{
如果(c<10)
{
//做事
}
}
相反


是的,它在页面上占用了更多的空间,但逻辑更为明显。

&
&
无论如何都是不同的运算符。通过相同的更正,可以使用
+
而不是
&
。@Olaf行为未指定且未定义。函数调用是一个序列点,但您仍然需要被解雇或获得“F-”级。我想这是个人品味的问题。很多人会说这样的代码很好。是的,那很好。
&&
从左到右求值。@anatolyg很多人不做太多调试。我实际的代码更像是
box\u intersect(&box\u a,&box\u b,&result)&&!box\u包含(&Biger\u box,&result)
,其中
box\u intersect()
如果存在交叉点,则返回true。不确定我是否同意该样式。它基本上类似于
if((ptr!=NULL)&&(ptr->count<10))
这是一个非常常见的构造。@olaf:正是嵌入表达式中的函数调用让我觉得它很难看-
f
返回一个值并更新
c
*,`然后与
c
进行比较。这对我来说是压缩了太多的操作。好的一点。隐藏的副作用是w这顶帽子也让我感觉不好。