18.5 — Early binding and late binding

In this lesson and the next, we are going to take a closer look at how virtual functions are implemented. While this information is not strictly necessary to effectively use virtual functions, it is interesting. Nevertheless, you can consider both sections optional reading.

When a C++ program is executed, it executes sequentially, beginning at the top of main(). When a function call is encountered, the point of execution jumps to the beginning of the function being called. How does the CPU know to do this?

When a program is compiled, the compiler converts each statement in your C++ program into one or more lines of machine language. Each line of machine language is given its own unique sequential address. This is no different for functions -- when a function is encountered, it is converted into machine language and given the next available address. Thus, each function ends up with a unique address.

Binding refers to the process that is used to convert identifiers (such as variable and function names) into addresses. Although binding is used for both variables and functions, in this lesson we’re going to focus on function binding.

Early binding

Most of the function calls the compiler encounters will be direct function calls. A direct function call is a statement that directly calls a function. For example:

Direct function calls can be resolved using a process known as early binding. Early binding (also called static binding) means the compiler (or linker) is able to directly associate the identifier name (such as a function or variable name) with a machine address. Remember that all functions have a unique address. So when the compiler (or linker) encounters a function call, it replaces the function call with a machine language instruction that tells the CPU to jump to the address of the function.

Let’s take a look at a simple calculator program that uses early binding:

Because add(), subtract(), and multiply() are all direct function calls, the compiler will use early binding to resolve the add(), subtract(), and multiply() function calls. The compiler will replace the add() function call with an instruction that tells the CPU to jump to the address of the add() function. The same holds true for subtract() and multiply().

Late Binding

In some programs, it is not possible to know which function will be called until runtime (when the program is run). This is known as late binding (or dynamic binding). In C++, one way to get late binding is to use function pointers. To review function pointers briefly, a function pointer is a type of pointer that points to a function instead of a variable. The function that a function pointer points to can be called by using the function call operator (()) on the pointer.

For example, the following code calls the add() function:

Calling a function via a function pointer is also known as an indirect function call. The following calculator program is functionally identical to the calculator example above, except it uses a function pointer instead of a direct function call:

In this example, instead of calling the add(), subtract(), or multiply() function directly, we’ve instead set pFcn to point at the function we wish to call. Then we call the function through the pointer. The compiler is unable to use early binding to resolve the function call pFcn(x, y) because it can not tell which function pFcn will be pointing to at compile time!

Late binding is slightly less efficient since it involves an extra level of indirection. With early binding, the CPU can jump directly to the function’s address. With late binding, the program has to read the address held in the pointer and then jump to that address. This involves one extra step, making it slightly slower. However, the advantage of late binding is that it is more flexible than early binding, because decisions about what function to call do not need to be made until run time.

In the next lesson, we’ll take a look at how late binding is used to implement virtual functions.

18.6 -- The virtual table
18.4 -- Virtual destructors, virtual assignment, and overriding virtualization

90 comments to 18.5 — Early binding and late binding

  • Brad

    When running the last example:

    Visual Studio gave the compile error: "potentially uninitialised local pointer variable 'pFcn' used".

    I resolved this error by initialising the line with nullptr:

    I thought I'd bring this to your attention in case you need to update the lesson. I assume setting it to nullptr doesn't break that section of code being an example of late binding.

    • Alex

      Makes since, since op might not be 0, 1, or 2. If that's the case, pFcn doesn't get mapped to anything. I've updated the lesson as you've suggested. Thanks!

  • Omri

    The following will not work: ... int n=6; int *pn; pn=n; //will not work as the left is a pointer to an int variable
    //and the right is an int variable. if written: pn=&n; will work.
    Case 2:
    int getint(int n){return n;}
    int main()
    { (*pgetint)(int); pgetint=getint; //works although left is a pointer and right is a function name.
    //This is what is new to me and needs some clarification.
    //Is function name a pointer too? Did we cover that?

  • Omri

    "add" is an address of a function.
    "pFcn" is a pointer to a function address.
    The fact that pFcn = add (etc) works is not typical to relation between an "object" and a "pointer to an object" as I understand up to here.
    It resembles more the relation between an object and a "reference to the object"...
    What am I missing here?

    • Alex

      I'm not sure what you're missing because I'm not sure I get what you're not understanding.

      Pointers hold addresses. Both variables and functions have addresses, so C++ will let you create variable pointers and function pointers.
      For what it's worth, you can also create references to functions, though these are less commonly used since you can't create arrays of references.

  • Mr C++


    • Alex

      No. Most function calls are resolved at compile time, and executed at run time.

      • Mr C++

        Exactly ! Because If that would not be the case, we wouldn't be ale to use runtime variables in arguments, no?
        Now, Let me ask you a Question :-
        Is the difference b/w late & early binding is that, the function calls are resolved at runtime & compile-time respectively ?

  • navid

    Hi sir
    I don't understand what is going on here!
    I already know what is binding especially static one but late binding? run time? I mean how decide on runtime? os does? how does that
    and I also have other question
    take look at this link, please
    those answers freak me out   I am java program and android developer but never hit to these things
    am I lose something?
    please light me

    • Alex

      Runtime just means "while your program is running" (as opposed to at compile time).

      In our sample program above, the compiler doesn't know which function will be called since we're calling the function indirectly (through a pointer). It can only be resolved at runtime.

  • Amol

    Is there any concept of late late binding in the context of COM or DCOM?

  • Amol

    Very Nice Explanation

  • Vivek

    Could you give an example where late-binding is advantageous/preferred?

    • Alex

      Generally you'll want to use early binding if you have a choice, as it tends to perform better and allows more types of error checking to occur. However, sometimes you don't have a choice. For example, late binding is the only way virtual functions can be implemented.

  • kannan

    Nice explanation. Thanks a lot.

  • zmike86

    Nice explanation. But I got slightly confused by the late-binding example, can the compiler inline the add or multiple function code in the switch block? If so, I think it can remove the function pointer code from the source, then '*pFcn' will not be needed.

  • GeekPro

    Can function pointer points to a class member function?

  • Aashish Raina

    Thanks a Million. Your explanation of concepts are precise and to the point.
    While reading your material, i say to myself , this was the kind of explanation i was looking.

    Keep up the good work

  • Naga

    Hi Alex,

    I have a small confusion in your function pointer example.
    int Add(int nX, int nY)
        return nX + nY;

    int main()
        // Create a function pointer and make it point to the Add function
        int (*pFcn)(int, int) = Add;
        cout << pFcn(5, 3) << endl; // add 5 + 3

        return 0;

    In above case, would function call be resolved in Compile time or Run time? I think it would be in compile time because we are directly making the function pointer to point to Add function. So compiler knows which function will be called at compile time and also there are no conditions like switch cases here as in your calculator program to wait for user input. Am I right?

    Hope you got my question.

    • Alex

      Normally, this would be resolved at runtime. However, a modern compiler might be able to optimize this into a call that could be resolved at compile-time. I don't know whether any modern compilers are smart enough to do this.

  • Devashish

    I am trying to clear where things become confusing to me:

    In the early binding example, compiler knows which function would be called in each case.
    calls Add if input is 0, calls Subtract if input is 1 and calls Multiply if input is 2.

    According to you:
    -> In the late binding example, the compiler doesn’t know which function will be called, because it doesn’t know what pFcn will be pointing to at the time it is invoked.

    Code extracted from late binding example. Can't compiler set a table or something like that to make pFcn point to different functions in those three cases? We are telling it which function should be pointed for each user input. I hope my question is clear.

    • Alex

      In theory, because this example is so simple, a compiler could optimize this code by converting the switch and function call into a direct function call. However, I'm not sure if modern compilers are that smart, and it might not work in more complicated cases.

      I'm not sure how using a table would help. pFcn already points to different functions in those three cases.

  • Devashish

    Typo: "The same holds true for for Subtract() and Multiply()"
    Multiple "for" in the last sentence of the paragraph under heading "Early binding".

    A confusion:
    You wrote this in Late binding
    "In some programs, it is not possible to know which function will be called until runtime (when the program is run)" (first line)

    "The compiler is unable to use early binding to resolve the function call pFcn(nX, nY) because it can not tell which function pFcn will be pointing to at compile time!"

    Now I am thinking about Early binding. Isn't the case is same with the early binding example. Program asks user to input a number (that is going to happen at runtime). User enters a number and then the appropriate function is called. That means compiler doesn't know (at compile time) which function has to be called, because calling a function is based on user input. Please help me get out of this confusion.

    • Alex

      Thanks for the typo fix. The article may be worded slightly ambiguously.

      As for the late binding, the thing to note here is that the compiler can't disambiguate which function will be called at compile time.

      In the early binding example, the compiler knows exactly which function will be called for each case (it just doesn't know whether that case will be executed or not, since that is user-input dependent).
      In the late binding example, the compiler doesn't know which function will be called, because it doesn't know what pFcn will be pointing to at the time it is invoked. It could be any function with a compatible prototype.

      • Very confused

        Alex, what do you mean the compiler doesn't know which function will be called in late binding ? For each case, isn't it stated exactly what pFcn will be pointing to ?

  • someone

    Good explanation!
    What about when I have something like this:
    class A{
        void virtual Foo(){//implementation}
    class B:A{///implementation};

    class C{
        void FooCall(A *a1, A &a2)
            A* a3 = new A();

    Are these static or dynamic bindings?

    • Alex

      Static -- the compiler knows exactly which function you're intending to call at compile time.

      • surya

        As usual, elegant explanations Alex.
        Functions of dynamic objects are static? but the memory will be allocated only during runtime. how will the compiler know the memory address during compile time?
        Interesting question tho @someone

        • Alex

          > Functions of dynamic objects are static?

          Yes. Remember that the syntax "object->function()" is just syntactical sugar for "function(object)", where the implicit object is passed as the "this" parameter of the function. The function itself is known at compile time. The address of the object, and its contents are not known until runtime.

  • sarthak

    Good explanation

  • ben

    very help full .nice presentation. Thank you

  • smru

    precisely explained concept..was very useful..

  • Augustine P A

    Nice explanation, very easy to understand.. But my personal opinion is that function pointers are quite interesting than conventional programming. Function Pointers provide some extremely interesting, e?cient and elegant programming techniques. You can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks.

  • nehemiah

    Woooohoooooo ALEX, Till now nobody cleared my doubt regarding even my college professors !!

    Thank you Alex for your mind blowing session !!

  • Ganesh

    Nice explanation, very easy to understand , I have already saved the web address.

  • it is good example for C++ late binding and early binding

  • mak

    the piece of code is an example of late binding itself. Put a code of Virtual functions. Virtual functions are perfect example of late binding or runtime polymorphism.

    these lines are clearly late binding example....

  • Max

    Nice and clear thank you.

  • sssss

    very good example

  • Arijit Chattopadhyay

    Good example.. Easy to understand

Leave a Comment

Put all code inside code tags: [code]your code here[/code]