diff --git a/1-ProceduralProgramming/4-Functions.ipynb b/1-ProceduralProgramming/4-Functions.ipynb index 0fffcf0133a30dd3277bf8a350d3e328ed08c984..19a94d783f2b88a793d602bfd674bfb4bcaca98f 100644 --- a/1-ProceduralProgramming/4-Functions.ipynb +++ b/1-ProceduralProgramming/4-Functions.ipynb @@ -21,13 +21,74 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Function definition\n", + "## Function declaration and definition\n", "\n", - "To be usable in a C++ instruction, a function must be __defined__ beforehand. This definition includes the name and type of the arguments, the type of the return value and the instruction block that make up the function.\n", + "### Function declaration\n", "\n", - "`void` is a special type to indicate a function doesn't return any value.\n", + "The aim of a **function declaration** is just to describe its prototype:\n", "\n", - "__BEWARE__: Functions can't be defined in blocks." + "- The return value of the function (or `void` if the function returns nothing).\n", + "- The number, type and ordering of the parameters (if any). Naming them specifically is entirely optional (but is useful if you choose to put your [Doxygen](../6-InRealEnvironment/6-Tools.ipynb#Doxygen) documentation along your functions declarations).\n", + "\n", + "Declaration ends by a semicolon `;`; the point of the declaration is to announce to the rest of the code that a function with this exact prototype exists and may be used elsewhere. \n", + "\n", + "Few examples of function declarations:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "int ComputeMinimum(int a, int b);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "void DoStuff(double); // naming the parameter is optional" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "int ReturnFive(); // providing a parameter is also optional...\n", + " // Don't bother Xeus-cling warning: it IS here a function declaration!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Due to the use of notebooks we won't need much proper function declaration, but we will revisit this [much later](../6-InRealEnvironment/2-FileStructure.ipynb) when we will see how a real project is written with different files involved." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Function definition" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On the other hand, the **function definition** aims at providing the implementation of the function that may (and should!) have been declared beforehand.\n", + "\n", + "In a function definition:\n", + "- No semicolon after the prototype\n", + "- A block follows the prototype instead; inside this block the implementation is written.\n", + "- Parameter may not be named, but if they are used (which should be the case most of the time hopefully...) you will need such a name in the implementation.\n", + "\n", + "For instance:" ] }, { @@ -38,30 +99,59 @@ "source": [ "#include <iostream>\n", "\n", - "void PrintDivision(int arg1, int arg2)\n", + "void PrintDivision(int numerator, int denominator) // no semicolon here!\n", "{\n", - " if (arg2 == 0)\n", + " if (denominator == 0)\n", " std::cout << \"Failure: division by zero!\" << std::endl;\n", " else\n", " {\n", " int division ;\n", - " division = arg1/arg2 ;\n", - " std::cout << arg1 << \" / \" << arg2 << \" = \" << division << std::endl ; \n", + " division = numerator / denominator ;\n", + " std::cout << numerator << \" / \" << numerator << \" = \" << division << std::endl ; \n", " }\n", "}" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and when the function is invoked at some point, the implementation above is direcly put in motion:" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "{\n", - " PrintDivision(12, 3);\n", - " PrintDivision(6, 0);\n", - " PrintDivision(15, 6);\n", - "}" + "int num = 3;\n", + "int denom = 2;\n", + "\n", + "PrintDivision(num, denom);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### A terminology note: _parameter_ and _argument_\n", + "\n", + "In the function above, I called `numerator` and `denominator` **parameters**, and you may also have heard the term **argument**.\n", + "\n", + "For the purists:\n", + "\n", + "- **parameter** is the name used when speaking about what is between the parenthesis during the function definition (`numerator` and `denominator` in the function definition)\n", + "- **argument** is what is passed when the function is effectively called within your code (`num` and `denom` in the above cell)\n", + "\n", + "I don't guarantee I am using the right term everywhere in the code: I'm not a purist and often use one for another (if you want to remember properly a helpful mnemotechnic is that **a**rguments are **a**ctual).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Functions can't be nested, or declared within blocks" ] }, { @@ -77,9 +167,9 @@ "metadata": {}, "outputs": [], "source": [ - "void function_1() // a function might have no arguments\n", + "void Function1() // a function might have no arguments\n", "{\n", - " void subfunction() // COMPILATION ERROR!\n", + " void Subfunction() // COMPILATION ERROR!\n", " {\n", " \n", " } \n", @@ -110,7 +200,7 @@ "source": [ "#include <iostream>\n", "\n", - "void increment_and_print(int i)\n", + "void IncrementAndPrint(int i)\n", "{\n", " ++i;\n", " std::cout << \"Inside the function: i = \" << i << std::endl;\n", @@ -119,7 +209,7 @@ "{\n", " int i = 5; // I could have named it differently - it doesn't matter as the scope is different!\n", "\n", - " increment_and_print(i);\n", + " IncrementAndPrint(i);\n", "\n", " std::cout << \"Outside the function: i = \" << i << std::endl; \n", "}" @@ -129,7 +219,30 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The `i` in the block body and in the function definition is not the same: one or the other could have been named differently and the result would have been the same." + "The `i` in the block body and in the function definition are not the same: one or the other could have been named differently and the result would have been the same:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#include <iostream>\n", + "\n", + "void IncrementAndPrint2(int local_argument)\n", + "{\n", + " ++local_argument;\n", + " std::cout << \"Inside the function: local_argument = \" << local_argument << std::endl;\n", + "}\n", + "\n", + "{\n", + " int i = 5; // I could have named it differently - it doesn't matter as the scope is different!\n", + "\n", + " IncrementAndPrint2(i);\n", + "\n", + " std::cout << \"Outside the function: i = \" << i << std::endl; \n", + "}" ] }, { @@ -138,7 +251,7 @@ "source": [ "### Passing arguments by reference\n", "\n", - "If we intended to modify the value of `i` outside the function, we should have passed it by reference:" + "If we intended to modify the value of `i` outside the function (and given the name of the function this is strongly hinted...), we should have passed it by reference:" ] }, { @@ -149,7 +262,7 @@ "source": [ "#include <iostream>\n", "\n", - "void increment_and_print_by_reference(int& i)\n", + "void IncrementAndPrintByReference(int& i)\n", "{\n", " ++i;\n", " std::cout << \"Inside the function: i = \" << i << std::endl;\n", @@ -158,7 +271,7 @@ "{\n", " int i = 5; // I could have named it differently - it doesn't matter as the scope is different!\n", "\n", - " increment_and_print_by_reference(i);\n", + " IncrementAndPrintByReference(i);\n", "\n", " std::cout << \"Outside the function: i = \" << i << std::endl; \n", "}" @@ -177,7 +290,7 @@ "metadata": {}, "outputs": [], "source": [ - "int compute_division(int arg1, int arg2, int& quotient, int& remainder)\n", + "int ComputeDivision(int arg1, int arg2, int& quotient, int& remainder)\n", "{\n", " if (arg2 == 0)\n", " return -1; // error code.\n", @@ -199,10 +312,10 @@ "{\n", " int quotient, remainder;\n", " \n", - " if (compute_division(5, 3, quotient, remainder) == 0)\n", + " if (ComputeDivision(5, 3, quotient, remainder) == 0)\n", " std::cout << \"5 / 3 = \" << quotient << \" with a remainder of \" << remainder << '.' << std::endl;\n", " \n", - " if (compute_division(5, 0, quotient, remainder) == 0)\n", + " if (ComputeDivision(5, 0, quotient, remainder) == 0)\n", " std::cout << \"5 / 0 = \" << quotient << \" with a remainder of \" << remainder << '.' << std::endl;\n", " else\n", " std::cout << \"Can't divide by 0!\" << std::endl;\n", @@ -217,7 +330,7 @@ "\n", "The function above gets two outputs: the quotient and the remainder of the euclidian division. Moreover, this function returns an error code: by convention this function returns 0 when everything is alright and -1 in case of a zero divider. \n", "\n", - "Using such an error code is a very common pattern in C, that might as well be used in C++... The issue is that it requires a lot of discipline from the user of the function: there are no actual incentive to use the return value! Just calling `compute_division()` as if it was a void function is perfectly fine (and yet completely ill-advised). We will see [later](../5-UsefulConceptsAndSTL/1-ErrorHandling.ipynb) the `exception` mechanism C++ recommends instead of error codes.\n", + "Using such an error code is a very common pattern in C, that might as well be used in C++... The issue is that it requires a lot of discipline from the user of the function: there are no actual incentive to use the return value! Just calling `compute_division()` as if it was a void function is perfectly fine (and yet completely ill-advised). We will see [later](../5-UsefulConceptsAndSTL/1-ErrorHandling.ipynb) the `exception` mechanism C++ recommends instead of error codes (and discuss a bit more error codes as well).\n", "\n", "Below is an example where things go awry due to the lack of check:" ] @@ -230,18 +343,18 @@ "source": [ "#include <iostream>\n", "\n", - "void print_division(int arg1, int arg2)\n", + "void PrintDivision(int arg1, int arg2)\n", "{\n", " int quotient, remainder;\n", " \n", - " compute_division(arg1, arg2, quotient, remainder); // the dev 'forgot' to check the error code.\n", + " ComputeDivision(arg1, arg2, quotient, remainder); // the dev 'forgot' to check the error code.\n", " \n", " std::cout << \"Euclidian division of \" << arg1 << \" by \" << arg2 << \" yields a quotient of \" \n", " << quotient << \" and a remainder of \" << remainder << std::endl; \n", "}\n", "\n", - "print_division(8, 5);\n", - "print_division(8, 0); // bug!\n" + "PrintDivision(8, 5);\n", + "PrintDivision(8, 0); // bug!\n" ] }, { @@ -249,17 +362,10 @@ "metadata": {}, "source": [ "The developer made two important mistakes:\n", - "* The return value of `compute_division` is not checked, so something is printed on screen.\n", + "* The return value of `ComputeDivision` is not checked, so something is printed on screen.\n", "* This is something completely out of control: quotient and remainder don't get a default value that would help to see if something is askew. The behaviour is undefined: you have no guarantee on the values the program will print (currently I see the same values as in the previous function call, but another compiler/architecture/etc... might yield another wrong value." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**UPDATE:** I still do not advise to use error codes, but the [nodiscard](https://en.cppreference.com/w/cpp/language/attributes/nodiscard) attribute introduced in C++ 17 helps your compiler to warn you when the return value was left unused." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -281,7 +387,7 @@ "source": [ "#include <iostream>\n", "\n", - "void increment_and_print_by_pointer(int* i)\n", + "void IncrementAndPrintByPointer(int* i)\n", "{\n", " *i += 1;\n", " std::cout << \"Inside the function: i = \" << *i << std::endl;\n", @@ -290,7 +396,7 @@ "{\n", " int i = 5; // I could have named it differently - it doesn't matter as the scope is different!\n", "\n", - " increment_and_print_by_pointer(&i);\n", + " IncrementAndPrintByPointer(&i);\n", "\n", " std::cout << \"Outside the function: i = \" << i << std::endl; \n", "}" @@ -316,7 +422,7 @@ "#include <iostream>\n", "\n", "//! \\brief Returns 1 if the value is positive, 0 if it is 0 and -1 if it's negative.\n", - "int sign(int a)\n", + "int Sign(int a)\n", "{\n", " if (a > 0)\n", " return 1;\n", @@ -329,7 +435,7 @@ "\n", "{\n", " for (int a = -3; a < 4; ++a)\n", - " std::cout << \"Sign of \" << a << \" = \" << sign(a) << std::endl;\n", + " std::cout << \"Sign of \" << a << \" = \" << Sign(a) << std::endl;\n", "}" ] }, @@ -349,7 +455,7 @@ "metadata": {}, "outputs": [], "source": [ - "auto sum(int a, int b) -> int // Currently doesn't compile in Xeus-cling environment\n", + "auto Sum(int a, int b) -> int // Currently doesn't compile in Xeus-cling environment\n", "{\n", " return a + b;\n", "}" @@ -368,7 +474,7 @@ "metadata": {}, "outputs": [], "source": [ - "auto sum(int a, int b) // compiles just fine in Xeus-cling\n", + "auto Sum(int a, int b) // compiles just fine in Xeus-cling\n", "{\n", " return a + b;\n", "}" @@ -385,7 +491,7 @@ "int a = 8;\n", "int b = -3;\n", "\n", - "std::cout << a << \" + \" << b << \" = \" << sum(a, b) << std::endl;" + "std::cout << a << \" + \" << b << \" = \" << Sum(a, b) << std::endl;" ] }, { @@ -406,15 +512,15 @@ "outputs": [], "source": [ "#include <string>\n", - "void f(); \n", + "void F(); \n", "\n", - "void f(int); // Ok\n", + "void F(int); // Ok\n", "\n", - "double f(int, double); // Ok\n", + "double F(int, double); // Ok\n", "\n", - "auto f(char) -> int; // Ok (alternate function syntax)\n", + "auto F(char) -> int; // Ok (alternate function syntax)\n", "\n", - "std::string f(double, int, char*); // Ok" + "std::string F(double, int, char*); // Ok" ] }, { @@ -432,9 +538,9 @@ "metadata": {}, "outputs": [], "source": [ - "void g(int);\n", + "void G(int);\n", "\n", - "int g(int); // COMPILATION ERROR" + "int G(int); // COMPILATION ERROR" ] }, { @@ -466,7 +572,7 @@ "source": [ "#include <iostream>\n", "\n", - "void h(double a)\n", + "void H(double a)\n", "{\n", " std::cout << \"h(double) is called with a = \" << a << '.' << std::endl;\n", "}\n" @@ -479,7 +585,7 @@ "outputs": [], "source": [ "#include <iostream>\n", - "void h(double* a) // Ok\n", + "void H(double* a) // Ok\n", "{\n", " std::cout << \"h(double*) is called with a = \" << *a << \"; a is doubled by the function.\" << std::endl;\n", " *a *= 2.;\n", @@ -493,7 +599,7 @@ "outputs": [], "source": [ "#include <iostream>\n", - "void h(double& a) // Ok... but not advised! (see below)\n", + "void H(double& a) // Ok... but not advised! (see below)\n", "{\n", " std::cout << \"h(double&) is called with a = \" << a << \"; a is doubled by the function.\" << std::endl;\n", " a *= 2.;\n", @@ -507,9 +613,9 @@ "outputs": [], "source": [ "{\n", - " h(5); // Ok\n", + " H(5); // Ok\n", " double x = 1.;\n", - " h(&x); // Ok\n", + " H(&x); // Ok\n", "}" ] }, @@ -528,7 +634,7 @@ "source": [ "{\n", " double x = 1.;\n", - " h(x); // COMPILATION ERROR: should it call h(double) or h(double& )?\n", + " H(x); // COMPILATION ERROR: should it call h(double) or h(double& )?\n", "}" ] }, @@ -547,7 +653,7 @@ "source": [ "{\n", " double x = 1.;\n", - " h(static_cast<double>(x)); // Ok\n", + " H(static_cast<double>(x)); // Ok\n", "}" ] }, @@ -567,7 +673,7 @@ "outputs": [], "source": [ "#include <iostream>\n", - "void h2(double a)\n", + "void H2(double a)\n", "{\n", " std::cout << \"h2(double) is called with a = \" << a << '.' << std::endl;\n", "}" @@ -580,7 +686,7 @@ "outputs": [], "source": [ "#include <iostream>\n", - "void h2(double* a) \n", + "void H2(double* a) \n", "{\n", " std::cout << \"h2(double*) is called with a = \" << *a << \"; a is doubled by the function.\" << std::endl;\n", " *a *= 2.;\n", @@ -597,10 +703,10 @@ " double x = 5.;\n", " double* ptr = &x;\n", " \n", - " h2(x); // call h2(double) \n", - " h2(ptr); // call h2(double*)\n", - " h2(*ptr); // call h2(double) \n", - " h2(&x); // call h2(double*)\n", + " H2(x); // call h2(double) \n", + " H2(ptr); // call h2(double*)\n", + " H2(*ptr); // call h2(double) \n", + " H2(&x); // call h2(double*)\n", "}" ] }, @@ -623,7 +729,7 @@ "source": [ "#include <iostream>\n", "\n", - "int min(int a, int b)\n", + "int Min(int a, int b)\n", "{\n", " std::cout << \"int version called!\" << std::endl;\n", " return a < b ? a : b;\n", @@ -638,7 +744,7 @@ "source": [ "#include <iostream>\n", "\n", - "double min(double a, double b)\n", + "double Min(double a, double b)\n", "{\n", " std::cout << \"double version called!\" << std::endl;\n", " return a < b ? a : b;\n", @@ -657,11 +763,11 @@ " float f1 { 3.14f }, f2 { -4.2f};\n", " short s1 { 5 }, s2 { 7 };\n", " \n", - " min(5, 7); // no ambiguity\n", - " min(i1, i2); // no ambiguity \n", - " min(f1, f2); // conversion to closest one\n", - " min(f1, d2); // conversion to closest one\n", - " min(s1, s2); // conversion to closest one \n", + " Min(5, 7); // no ambiguity\n", + " Min(i1, i2); // no ambiguity \n", + " Min(f1, f2); // conversion to closest one\n", + " Min(f1, d2); // conversion to closest one\n", + " Min(s1, s2); // conversion to closest one \n", "}" ] }, @@ -680,7 +786,7 @@ "source": [ "{\n", " unsigned int i1 { 5 }, i2 { 7 };\n", - " min(i1, i2); // COMPILATION ERROR: no 'obvious' best candidate!\n", + " Min(i1, i2); // COMPILATION ERROR: no 'obvious' best candidate!\n", "}" ] }, @@ -692,7 +798,7 @@ "source": [ "{\n", " long i1 { 5 }, i2 { 7 };\n", - " min(i1, i2); // COMPILATION ERROR: no 'obvious' best candidate!\n", + " Min(i1, i2); // COMPILATION ERROR: no 'obvious' best candidate!\n", "}" ] }, @@ -713,7 +819,7 @@ " float f1 { 5.f };\n", " int i1 { 5 };\n", " \n", - " min(f1, i1); // for i1 the 'int'version is better, but for f1 the 'double' is more appropriate...\n", + " Min(f1, i1); // for i1 the 'int'version is better, but for f1 the 'double' is more appropriate...\n", "}" ] }, @@ -933,12 +1039,12 @@ "\n", "{\n", " // Locally defined function.\n", - " auto square = [](double x) -> double\n", + " auto Square = [](double x) -> double\n", " {\n", " return x * x;\n", " };\n", " \n", - " std::cout << square(5.) << std::endl;\n", + " std::cout << Square(5.) << std::endl;\n", "}" ] }, @@ -964,18 +1070,18 @@ "\n", "{\n", " // Locally defined function.\n", - " auto square = [](double x) \n", + " auto Square = [](double x) \n", " {\n", " return x * x;\n", " };\n", " \n", - " auto cube = [](double x)\n", + " auto Cube = [](double x)\n", " {\n", " return x * x * x;\n", " };\n", "\n", " std::cout << \"Are the lambda prototypes the same type? \" \n", - " << (std::is_same<decltype(square), decltype(cube)>() ? \"true\" : \"false\") << std::endl;\n", + " << (std::is_same<decltype(Square), decltype(Cube)>() ? \"true\" : \"false\") << std::endl;\n", "}" ] }, @@ -999,12 +1105,12 @@ "{\n", " int a = 5;\n", " \n", - " auto a_plus_b = [](int b)\n", + " auto APlusB = [](int b)\n", " {\n", " return a + b;\n", " };\n", " \n", - " std::cout << a_plus_b(3) << std::endl; // COMPILATION ERROR: a is not known inside the lambda body.\n", + " std::cout << APlusB(3) << std::endl; // COMPILATION ERROR: a is not known inside the lambda body.\n", "}" ] }, @@ -1019,12 +1125,12 @@ "{\n", " int a = 5;\n", " \n", - " auto a_plus_b = [a](int b) // Notice the `[a]` here!\n", + " auto APlusB = [a](int b) // Notice the `[a]` here!\n", " {\n", " return a + b;\n", " };\n", " \n", - " std::cout << a_plus_b(3) << std::endl;\n", + " std::cout << APlusB(3) << std::endl;\n", "}" ] }, @@ -1046,12 +1152,12 @@ "{\n", " int a = 5;\n", " \n", - " auto add_to_a = [&a](int b) // Notice the `[&a]` here!\n", + " auto AddToA = [&a](int b) // Notice the `[&a]` here!\n", " {\n", " a += b;\n", " };\n", " \n", - " add_to_a(3);\n", + " AddToA(3);\n", " std::cout << a << std::endl; \n", "}" ] @@ -1192,7 +1298,7 @@ "metadata": {}, "outputs": [], "source": [ - "int multiply(int a, int b)\n", + "int Multiply(int a, int b)\n", "{\n", " return a * b;\n", "}" @@ -1204,7 +1310,7 @@ "metadata": {}, "outputs": [], "source": [ - "int add(int a, int b)\n", + "int Add(int a, int b)\n", "{\n", " return a + b;\n", "}" @@ -1216,8 +1322,8 @@ "metadata": {}, "outputs": [], "source": [ - "PrintFunctionCall(multiply, 5, 6);\n", - "PrintFunctionCall(add, 5, 6);" + "PrintFunctionCall(Multiply, 5, 6);\n", + "PrintFunctionCall(Add, 5, 6);" ] }, { @@ -1237,7 +1343,7 @@ "source": [ "## A very special function: __main__\n", "\n", - "Any C++ program must include one and only one `main` function. Its prototype is __int main(int argc, char** argv)__ where:\n", + "Any C++ program must include one and only one `main` function. Its prototype is `int main(int argc, char** argv)` where:\n", "* __argc__ is the number of arguments given on the command line. This is at least 1: the name of the program is one argument. For instance, if your program creates a _isPrime_ executable that takes an integer as argument, `argc` will return 2.\n", "* __argv__ is the list of arguments read on the command line, given as an array of C-strings. In our _isPrime_ example, __argv[0]__ is _isPrime_ and __argv[1]__ is the integer given.\n", "\n", @@ -1271,7 +1377,7 @@ "metadata": {}, "outputs": [], "source": [ - "inline double square(double x)\n", + "inline double Square(double x)\n", "{\n", " return x * x;\n", "}" @@ -1291,7 +1397,7 @@ "outputs": [], "source": [ "{\n", - " square(5.); // The compiler might substitute 5. * 5. to the actual function call here\n", + " Square(5.); // The compiler might substitute 5. * 5. to the actual function call here\n", "}" ] }, @@ -1306,7 +1412,7 @@ "* `inline` definitions must be provided in header file (see the [upcoming notebook](../6-InRealEnvironment/2-FileStructure.ipynb) that will deal extensively with the file structure to follow in a C++ program). You therefore pay the price in compilation time whenever you change its implementation (as we'll see more in detail in aforementioned notebook, modifying a header file yields more re-compilation).\n", "* Don't bother inlining functions with any complexity whatsoever, so if your function includes a loop or is more than few lines long, write a normal function instead. \n", "\n", - "The `square` example was sound: this is typically the kind of functions that might be inlined.\n", + "The `Square` example was sound: this is typically the kind of functions that might be inlined.\n", "\n", "Just to finish, my comparison with a macro was not fair; one of the known drawback of macros is perfectly handled: \n" ] @@ -1317,7 +1423,7 @@ "metadata": {}, "outputs": [], "source": [ - "#define SQUARE(x) ((x) * (x))" + "#define SQUARE(x) ((x) * (x)) // macro" ] }, { @@ -1330,7 +1436,7 @@ "\n", "{\n", " double x = 5.;\n", - " std::cout << square(++x) << std::endl; \n", + " std::cout << Square(++x) << std::endl; \n", "}\n", "\n", "{\n",