Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

De Morgan's Law optimization with overloaded operators

Every programmer should know that:

De Morgan 1
De Morgan 2
(De Morgan's Laws)

Under some circumstances, in order to optimize the program, it may happen that compiler modifies (!p && !q) to (!(p || q)).

The two expressions are equivalent, and it makes no difference evaluating the first or the second.
But in C++ it is possible to overload operators, and the overloaded operator may not always respect this property. So transforming the code this way will actually modify the code.

Should the compiler use De Morgan's Laws when !, || and && are overloaded?

like image 980
Alex Avatar asked Oct 14 '15 08:10

Alex


2 Answers

Note that:

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 operands.

... Because the short-circuiting properties of operator&& and operator|| do not apply to overloads, and because types with boolean semantics are uncommon, only two standard library classes overload these operators ...

Source: http://en.cppreference.com/w/cpp/language/operator_logical (emphasis mine)

And that:

If there is a user-written candidate with the same name and parameter types as a built-in candidate operator function, the built-in operator function is hidden and is not included in the set of candidate functions.

Source: n4431 13.6 Built-in operators [over.built] (emphasis mine)

To summarize: overloaded operators behave like regular, user-written functions.

NO, the compiler will not replace a call of a user-written function with a call of another user-written function. Doing otherwise would potentially violate the "as if" rule.

like image 173
sergej Avatar answered Sep 21 '22 17:09

sergej


I think that you have answered your own question: no, a compiler can not do this. Not only the operators can be overloaded, some can not be even defined. For example, you can have operator && and operator ! defined, and operator || not defined at all.

Note that there are many other laws that the compiler can not follow. For example, it can not change p||q to q||p, as well as x+y to y+x.

(All of the above applies to overloaded operators, as this is what the question asks for.)

like image 42
Petr Avatar answered Sep 19 '22 17:09

Petr