I was writing something similar to the code below and I accidentally called the same function inside the body of the function definition.
double function(double &value)
{
//do something with a here
if(some condition)
{
function(a);
}
return a;
}
Consider something of the form:
int function(int &m) {
m = 2*m;
if(m < 20)
{
function(m);
}
return m;
};
int main() {
int a = 2;
std::cout <<"Now a = "<<function(a);
return 1;
}
According to me this should not run let alone compile. But it does run and gives out the correct result
Now a = 32
I have called the function before I even 'finished' defining it. Yet, it works. Why?
A function calling itself is known as a recursive function. This works because the compiler only needs the declaration of a function, not its definition, for you to be able to call it. The first line of the definition also serves as a declaration. (For details, see § 8.4.1.2 of the C++11 standard.)
Recursion is well-suited to solve many problems. The typical example of a recursive function is the factorial
function. It is defined as factorial(n) = n * factorial(n-1)
.
You can try running this piece of code to get a bit more understanding of what happens when a function calls itself:
#include <iostream>
int factorial(unsigned int n)
{
std::cout << "Computing factorial of " << n << "\n";
int result;
if (n == 0) {
result = 1;
} else {
result = n * factorial(n-1);
}
std::cout << "factorial(" << n << ") = " << result << "\n";
return result;
}
int main()
{
factorial(5);
}
For more information about declaration vs. definition, see this answer. The Wikipedia page about the One Definition Rule might also be helpful.
It's because you misunderstand what "defining" a function means.
First of all let's get the semantics correct: In order to refer to a function you just need its declaration and not its complete implementation.
Typically, there are two steps in creating an executable: 1) Compiling and 2) Linking.
The compiling step works out that the syntax of each piece is okay for each function. In order to compile you need the core language keywords or properly declared symbols. The compiler puts these together but does not resolve whether or not those symbols actually point to real objects in the executable. An object is either bits of data, or bits of instruction. Usually these blobs are called data-segments and text-segments in an object file.
It's in the linking step that each of the blobs, which is still identified using symbols is put together to see if all the references in the code have corresponding blobs.
Now that you know that all you need to evaluate whether or not syntax is correct (compilation step) is the declaration. The fact that you have a symbol reference within the body of the function itself is not a problem at all.
What you are doing above is short-hand for the following:
int function(int &m); // implicit declaration
int function(int &m) {
m = 2*m;
if(m < 20)
{
function(m); // this only requires the declaration to be accepted
// by the compiler.
}
return m;
};
int main() {
int a = 2;
std::cout <<"Now a = "<<function(a);
return 1;
}
This ability is very important because it's fundamental to creating recursive functions. Some problems can be solved with recursion a lot more elegantly than with iterations, especially when you start throwing in n-way recursive functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With