Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - Calling a function inside the same function's definition

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?

like image 466
Colorless Photon Avatar asked Jun 30 '13 05:06

Colorless Photon


2 Answers

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.

like image 131
Lstor Avatar answered Nov 03 '22 01:11

Lstor


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.

Compiling

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.

Linking

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.

Self-reference

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.

like image 31
Ahmed Masud Avatar answered Nov 03 '22 01:11

Ahmed Masud