In C conditional-oriented operators evaluate to either 1
or 0
of type int
(even if it does have dedicated _Bool
type). Referring to C11 N1570 draft:
C11 §6.5.8/6 Relational operators
Each of the operators
<
(less than),>
(greater than),<=
(less than or equal to), and>=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.107) The result has typeint
.C11 §6.5.9/3 Equality operators
The
==
(equal to) and!=
(not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has typeint
. For any pair of operands, exactly one of the relations is true.C11 6.5.13/3 Logical AND operator
The
&&
operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has typeint
.C11 6.5.14/3 Logical OR operator
The
||
operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has typeint
.
As I checked C++ seems to be different in this matter, as in following example (see http://ideone.com/u3NxfW):
#include <iostream>
#include <typeinfo>
int main() {
double x = 10.0;
std::cout << typeid(x <= 10.0).name() << std::endl;
return 0;
}
outputs b
, which as I guess indicates bool
type. Does C++ guarantee that all of these operators always evaluate to bool
type (in contrast to C)?
C does not have boolean data types, and normally uses integers for boolean testing. Zero is used to represent false, and One is used to represent true.
The else statement With if statements, our programs can execute a set of instructions only if the condition is true. If we want our programs to execute a different set of instructions when the condition is false, then we can use an else statement.
The logical operator *NOT (or ¬) is used to negate logical variables or constants.
No, because of operator overloading. This has been mentioned before, but I can give the real life example of expression templates. The idea, generally, is to allow writing "lazy" expressions (that is, really, function objects or ASTs) with syntax that is very similar to the normal, eager use of logical operators. Typically, many other operators, in particular arithmetic operators are also, overloaded.
For instance, one design goal of Boost.Lambda was to simplify the use of algorithms:
std::string str;
// ...
std:.string::iterator firstA = std::find_if(str.begin(), str.end(), _1 == 'a' || _1 == 'A');
Previously, in "pure" C++98, it was generally necessary to write numerous named functions or function objects before many standard algorithms could be used effectively.
Since C++11, Boost.Lambda is not as useful any more since lambda expressions have been added to the core language. There are still numerous EDSLs (embedded domain-specific languages) where C++11 lambdas cannot replace expression templates though, e.g. you may want to generate SQL command strings directly from a C++ EDSL in a way similar to LINQ in .NET, but as a portable library solution. Another example: the VexCL library uses expression templates to generate GPU kernels.
This is probably the only legitimate use of non-bool return types for overloaded logical operators, but it's not generally considered esoteric.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With