At my work I tried to use this construction:
if (repl && (repl = replaced.count(*l))) {
// repl isn't used here
...
}
and in my mind it should work the same way as
bool newRepl = replaced.count(*l);
if (repl && newRepl) {
// repl isn't used here
...
}
repl = newRepl;
because expressions in &&
evaluate from left to right, but unexpectedly it's not.
Is it a not specified construction in C or I don't correctly understand how it should work?
Example of code with a problem:
std::set<int> set{3, 4, 6};
bool repl = false;
for (size_t i = 3; i < 7; i) {
if (repl && (repl = set.count(i))) {
std::cout << "strangeif" << std::endl;
}
}
output:
std::set<int> set{3, 4, 6};
bool repl = false;
for (size_t i = 3; i < 7; i) {
bool newRepl = set.count(i);
if (repl && newRepl) {
std::cout << "strangeif" << std::endl;
}
repl = newRepl;
}
output: strangeif
CodePudding user response:
&&
is short-circuiting. Your original code is equivalent to this:
if (repl) {
repl = replaced.count(*l))
if (repl) {
// repl isn't used here
...
}
}
CodePudding user response:
In addition to the answer of @Sebastian Redl which is also a good answer, i would like to clearify the concept.
the following code would help to understand the concept of short-circuiting
.
#include <iostream>
bool printret(bool ret){
std::cout << "printret call: " << ret << std::endl;
return ret;
}
int main()
{
std::cout << "first test :" << std::endl;
if(printret(true) && printret(false)){}
std::cout << "second test:" << std::endl;
if(printret(false) && printret(true)){}
return 0;
}
Output :
first test :
printret call: 1
printret call: 0
second test:
printret call: 0
the second test is literally ignoring the expression in the right side of &&
since the first expression (in the left side of &&
) returns false.