News for hackers. Stuff that matters.
Re:Named Booleans prevent C++ bugs and save you time by meindnoch on Saturday February 18, 2023 @07:16AM (#34846334)
You're wrong.

  if (cheapCheck() && expensiveCheck()) { ... }
is not equivalent to

  bool cheap = cheapCheck();
  bool expensive = expensiveCheck();
  if (cheap && expensive) { ... }
unless we're in a lazy pure functional language.
Re:Named Booleans prevent C++ bugs and save you time by lazypenguin on Saturday February 18, 2023 @07:32AM (#34846427)
Can you prove this?
Re:Named Booleans prevent C++ bugs and save you time by drdec on Saturday February 18, 2023 @07:47AM (#34846508)
It's easy enough to verify, just add a side effect to the second function. Just think of them as process functions returning success flags.
Re:Named Booleans prevent C++ bugs and save you time by ninkendo on Saturday February 18, 2023 @07:50AM (#34846523)
I think the idea is that if there's observable behavior in unconditionally calling the expensive function, the compiler can't skip it without altering the program behavior. Whereas if they're called as part of the if condition, the compiler can always safely skip the second function (and it's documented that it must do so, due to "short circuit" semantics) if the first function is false.

The ability of the compiler to skip the expensive function in both cases are characteristics of a "lazy" language, ie. you can assign an expensive function to a value, but the actual function isn't run until the variable is needed. Languages like C++ can't do this because it would alter the program's behavior if cheapCheck() does return true, because suddenly it would have to call expensiveCheck() after cheapCheck() (rather than before), which is an observably different behavior for the optimization to cause.

Re:Named Booleans prevent C++ bugs and save you time by lazypenguin on Saturday February 18, 2023 @08:02AM (#34846593)
My mistake for reading HN too early in the morning. You and the other poster are right.
Re:Named Booleans prevent C++ bugs and save you time by ninkendo on Saturday February 18, 2023 @08:08AM (#34846642)
(Fun fact: I read meindnoch's comment right after I woke up and I, too, was about to reply to them with a godbolt listing to show that it would compile to the same thing, only to realize I completely forgot about short-circuit semantics. So you're not alone!)
Re:Named Booleans prevent C++ bugs and save you time by bicolao on Saturday February 18, 2023 @09:05AM (#34847005)
It's part of the language [1] [2]

> Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both

[1] https://en.cppreference.com/w/cpp/language/operator_logical [2] https://en.wikipedia.org/wiki/Short-circuit_evaluation

Re:Named Booleans prevent C++ bugs and save you time by tialaramex on Saturday February 18, 2023 @12:25PM (#34848780)
Note that (CPP reference will also tell you) this only applies to the built-in operator.

If the operator has been overloaded which is easy to write in C++, then too bad - the overload doesn't short circuit.

I think if you can't figure out a way to preserve the short-circuit feature then having a way to overload this operator in your language is stupid. It is, I would say, unsurprising to me that C++ did it anyway.

EtA:: It feels like in say Rust you could pull this off as a trait LogicalAnd implemented on a type Foo, with a method that takes two parameters of type FnOnce() -> Foo , and then the compiler turns (some_complicated_thing && different_expression) where both of the sub-expressions are of type Foo into something like:

  {
    let a = (|| some_complicated_thing);
    let b = (|| different_expression);
    LogicalAnd::logical_and(a, b)
  }
To deliver the expected short-circuiting behaviour in your implementation of the logical_and method, you just don't execute b unless you're going to care about the result.
Re:Named Booleans prevent C++ bugs and save you time by IshKebab on Saturday February 18, 2023 @07:50AM (#34846526)
That depends. In some cases the compiler will be able to determine that `expensiveCheck()` has no side effects and make them equivalent. But you can't really rely on it.

And in any case the author misidentified the problem and solution. The problem is that C++ coerces bool to int. I'm 99% sure there's a warning for that that you can turn into an error.

Re:Named Booleans prevent C++ bugs and save you time by kqr on Saturday February 18, 2023 @01:03PM (#34849249)
Ah, the mythical sufficiently smart compiler! http://wiki.c2.com/?SufficientlySmartCompiler
Re:Named Booleans prevent C++ bugs and save you time by IshKebab on Saturday February 18, 2023 @05:32PM (#34851784)
That's a different thing - the "sufficiently smart compiler" is postulating that it doesn't matter if a language is not very high performance because somehow magically there will one day be a compiler that can just figure out how to optimise the code in every case.

I'm just saying that in this particular case, sometimes the compiler will be able to optimise it but you can't rely on it.

https://godbolt.org/z/WshcfWPEh

Re:Named Booleans prevent C++ bugs and save you time by grok22 on Saturday February 18, 2023 @01:05PM (#34849266)
In theory, if this is the case (or the case in other comments about null pointer use and such), you would/could write it as:

   bool cheap = cheapCheck();
   bool expensive = cheap && expensiveCheck();
   if (expensive) { ... }