#include // FIND THE BUG // // The function verbose_equality(a, b) tests whether its // two arguments are equal. If they are equal, it also // prints // // The values a and b are equal! // // before returning true. // // First, can you choose values for x and y so that the // program produces the output // // The values ? and ? are equal! // Your two values are equal. // // If so, give values for x and y. // // Second, can you choose values for x, y and z so that // the program produces the output // // The values ? and ? are equal! // The third does not equal the first, or it equals // the second. // // If so, give values for x, y and z. If not, explain why // this output is impossible. // // Remember that C++ uses short-circuit evaluation when // evaluating expressions involving && and ||. // Function declarations int main(); bool verbose_equality( double a, double b ); // Function definitions int main() { double x{}; std::cout << "Enter a real number: "; std::cin >> x; double y{}; std::cout << "Enter another real number: "; std::cin >> y; if ( verbose_equality( x, y ) ) { std::cout << "Your two values are equal." << std::endl; return 0; } double z{}; std::cout << "Enter a third real number: "; std::cin >> z; if ( (x != z) || verbose_equality( z, y ) ) { std::cout << "The third does not equal the first, " << "or it equals the second." << std::endl; } return 0; } bool verbose_equality( double a, double b ) { if ( a == b ) { std::cout << "The values " << a << " and " << b << " are equal!" << std::endl; return true; } else { return false; } } // Hint: // // For the first question, when does // // verbose_equality( x, y ) // // print its message and return true? // // For the second question, remember that in // // (x != z) || verbose_equality( z, y ) // // the second operand is evaluated only if the first // operand is false. // // Therefore, what must be true about x and z before // verbose_equality(z, y) can even be called? // Solution to the first question: // // Yes. // // For example, enter // // x = 2 // y = 2. // // The call // // verbose_equality( x, y ) // // prints // // The values 2 and 2 are equal! // // and returns true. The body of the 'if' statement then // prints // // Your two values are equal. // // The program then returns from main(), so the user is // never asked to enter z. // Solution to the second question: // // No. This output is impossible. // // To see why, suppose verbose_equality(z, y) prints // // The values ? and ? are equal! // // in the second 'if' statement. // // The condition is // // (x != z) || verbose_equality( z, y ). // // Because || uses short-circuit evaluation, // verbose_equality(z, y) is called only if // // x != z // // is false. // // Therefore, // // x == z. // // For verbose_equality(z, y) to print its message, we // must also have // // z == y. // // Combining these two equalities gives // // x == z == y. // // In particular, // // x == y. // // But if x == y, the earlier call // // verbose_equality( x, y ) // // would have returned true, and main() would already have // returned 0. // // The program therefore could never reach the statement // that asks the user to enter z. // // Consequently, there are no values of x, y and z that // can produce the requested second output. // There is another useful observation about the second // condition: // // (x != z) || verbose_equality( z, y ) // // If x != z, the first operand of || is already true. // The function verbose_equality(z, y) is therefore not // called. // // If x == z, the function is called, but for it to print // its message, z must equal y. That would imply x == y, // which the program has already established is false. // // Thus, if execution reaches the second 'if' statement, // verbose_equality(z, y) can never print its message.