Grzegorz Szpetkowski
Grzegorz Szpetkowski

Reputation: 37914

Are conditional expressions in C++ always of bool type?

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 type int.

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 type int. 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 type int.

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 type int.

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)?

Upvotes: 14

Views: 1096

Answers (2)

ouah
ouah

Reputation: 145829

Contrary to C, in C++, relational operators, equality operators and logical operators (logical AND, logical OR and logical negation) all yield a value of type bool.

For example:

(C++11, 5.9p1 Relational operators) "[...] The type of the result is bool."

EDIT: for the sake of completeness, all the operators listed above can be overloaded and thus the resulting type can be changed. See Arne Vogel answer for real life example.

Upvotes: 12

Arne Vogel
Arne Vogel

Reputation: 6666

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.

Upvotes: 14

Related Questions