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这顶帽子也让我感觉不好。