Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between early binding and late binding in C++?

Tags:

c++

oop

Since i'm studying object oriented programming language it is quite better than C and pretty new concepts. I'm confused with early binding and late binding so my question is

What is the difference between early binding and late binding in C++?

like image 783
Raghavendra Bailammanavar Avatar asked Dec 10 '22 17:12

Raghavendra Bailammanavar


1 Answers

Consider the following code:

void foo()
{
  std::cout << "A\n";
}
void bar()
{
  std::cout << "B\n";
}

// returns a callable object which either refers to foo or bar
// depending on user input during runtime
std::function<void()> maker()
{
  std::cout << "Please give a number:\n";
  auto x = 0.0;
  if (std::cin >> x && x > 50.0)
  { // if we get a valid value from the console and if it is > 50
    // we return a callable that refers to foo
    return{ &foo };
  }
  // otherwise we return a callable that refers to bar
  return{ &bar };
}

A simple call to foo or bar can be resolved at compile time (the function binding can happen early/during compilation) but using maker() will result in late binding because it is actually unknown to the compiler which function will be called:

auto f = maker();
f(); // whether foo or bar is called depends 
     // on the user input during maker execution

The same is true for all other methods of dynamic dispatching (i.e. virtual function calls).

If the compiler is not able to prove (at compile time) that (indepedant of the runtime information) a specific function is to be called at a certain point of the program flow, late function binding is used to resolve the appropriate action at runtime. Otherwise early function binding is used to resolve the call at compile time (which may not necessarily be an actual call but can also be done via inlining).


Edit: Given the following source, gcc (according to godbolt) is performing late binding with -O0 for both, foo and bar while from -O2 the assembly output show a
call    t_deriv_1::f() const

in the assembly of bar because make_bar is known when bar is compiled and is examined to find that the type which is actually returned is always t_deriv_1.

struct t_base
{
  virtual int f() const = 0;
  virtual ~t_base() {}
};
struct t_deriv_1 : t_base
{
  int f() const override final;
};
struct t_deriv_2 : t_base
{
  int f() const override final;
};

t_base * make_foo();
t_base * make_bar()
{
  return new t_deriv_1;
}

void foo()
{
  t_base * p = make_foo();
  p->f();
  delete p;
}

void bar()
{
  t_base * p = make_bar();
  p->f();
  delete p;
}
like image 139
Pixelchemist Avatar answered Jan 11 '23 23:01

Pixelchemist