#include #include #include #include /*************************************************** * Finding bugs with default arguments * * Each of the following three functions attempts * to use a default argument. * * In each case, there is a syntax error or an error * in the use of default arguments. * * Before compiling the program, try to determine * what is wrong with each function. * * Once you think you have found all three problems, * fix them and try compiling the program. * * Scroll down for explanations and solutions. ***************************************************/ // Function declarations int main(); bool compare( int const m, int const n = 0 ); double distance( double const x, double const y, bool const absolute = true, bool const finite ); double distance( double const x1, double const y1, double const x2, double const y2, unsigned int const p == 1 ); // Function definitions int main() { std::cout << std::boolalpha; std::cout << compare( 4 ) << std::endl; std::cout << compare( 4, 4 ) << std::endl; std::cout << std::endl; std::cout << distance( 3.2, 5.7 ) << std::endl; std::cout << std::endl; std::cout << distance( 0.2, 0.5, 0.1, 0.8, 1 ) << std::endl; std::cout << distance( 0.2, 0.5, 0.1, 0.8, 2 ) << std::endl; std::cout << distance( 0.2, 0.5, 0.1, 0.8, 100 ) << std::endl; return 0; } /*************************************************** * compare * * Return true if the two integers are equal. ***************************************************/ bool compare( int const m, int const n = 0 ) { return m == n; } /*************************************************** * distance * * Calculate the difference between x and y. * * If absolute is true, return the absolute * difference. * * If finite is true and the resulting difference * is not finite, return NaN. ***************************************************/ double distance( double const x, double const y, bool const absolute, bool const finite ) { double const difference{ y - x }; if ( finite && !std::isfinite( difference ) ) { return std::numeric_limits::quiet_NaN(); } else if ( absolute ) { return std::abs( difference ); } else { return difference; } } /*************************************************** * distance * * Calculate the p-norm distance between the points * * (x1, y1) and (x2, y2): * * (|x1 - x2|^p + |y1 - y2|^p)^(1/p). * * We require p > 0. ***************************************************/ double distance( double const x1, double const y1, double const x2, double const y2, unsigned int const p ) { assert( p > 0 ); return std::pow( std::pow( std::abs( x1 - x2 ), p ) + std::pow( std::abs( y1 - y2 ), p ), 1.0/p ); } // Solutions: // // There are three different problems involving // default arguments. // // // 1. A default argument should not be repeated. // // The declaration says // // bool compare( int const m, // int const n = 0 ); // // but the definition also says // // bool compare( int const m, // int const n = 0 ) { // // The default argument should be specified in the // function declaration and should not be repeated // in the function definition. // // Thus, the definition should begin // // bool compare( int const m, // int const n ) { // // // // 2. Default arguments must occur at the end. // // The declaration // // double distance( // double const x, // double const y, // bool const absolute = true, // bool const finite // ); // // gives absolute a default argument but does not // give the following parameter finite a default. // // Once one parameter has a default argument, all // parameters following it must also have default // arguments. // // For example, we could use // // bool const absolute = true, // bool const finite = true // // so that the declaration becomes // // double distance( // double const x, // double const y, // bool const absolute = true, // bool const finite = true // ); // // // // 3. A default argument uses =, not ==. // // The declaration // // unsigned int const p == 1 // // incorrectly uses the equality operator ==. // // It should be // // unsigned int const p = 1. // // Thus, the corrected declaration is // // double distance( // double const x1, // double const y1, // double const x2, // double const y2, // unsigned int const p = 1 // ); // // // With these three corrections, all of the calls in // main() compile and run.