Why are virtual methods considered early?

One definition of binding is that it replaces function names with memory addresses.

a) So, I assume that early binding means that function calls are replaced with memory addresses during the compilation process, and with late binding, this replacement occurs at runtime?

b) Why are virtual methods also considered early (thus, the target method is found at compile time, and code is created that will invoke this method)? As far as I know, using virtual methods, calling the actual method is allowed only at runtime, and not at compile time ?!

thanks


EDIT:

1)

A a=new A(); aM(); 

As far as I know, at compile time it is not known where on the heap (in this way, which has a memory address) an instance of a will be created at runtime. Now, with early binding, function calls are replaced with memory addresses during the compilation process. But how can a compiler replace a function call with a memory address if it does not know where on the heap the object a will be created at runtime (here Im, assuming that the address of the aM method will also be in the same memory location as a )?

2)

v-table calls are neither early nor late. Instead, there is an offset to the function pointer table. The offset is fixed at compile time, but which table is selected from the function pointer depends on the type of runtime of the object (the object contains a hidden pointer to its v-table), so the final address of the function is at runtime.

But if an object of type T is created through reflection (and the application does not even know about the existence of type T ), then how does the compilation point of entry exist for this type of object?

+4
source share
3 answers

Late binding

With late binding, all you have is the name of the method. At compile time, you do not know if the method exists. This is called duck printing in languages โ€‹โ€‹such as Ruby or Python.

Late binding is slow because you need to search for a function by name. This is also dangerous because you are not protected from minor spelling errors.

Prior to version 4, C # does not support late binding, except to explicitly call the reflection API.

Early binding

When using early binding, you are compiling the actual method. This method can be assigned directly or it can be a slot in the V-table. In any case, you are not required to refuse the MissingMethod exception.

History

Visual Basic was well known for both early and late binding, but due to its other limitations, it was never considered a true dynamic language. At the same time, versions prior to 7 (aka VB.NET) had very poor support for forced early binding, which made it difficult to call it a static language.

With .NET 4, we can say that both C # and VB offer most of the functions expected from both static and dynamically typed languages.

At some point, Java mistakenly stated that it had later binding support, when it had only early restrictions, OOP style V-tables. Over the years, this has led to confusion.

+6
source

Virtual methods are early when the compiler knows the exact type at compile time.

If the compiler does not have an exact type, it will instead generate a vtable lookup style binding style.

+1
source

The virtual method call may be early, as Joshua explains (i.e. the compiler can see the exact type of the object, no polymorphism occurs), or it can be done through a v-table.

C # only makes the last binding when you use reflection (and in the next version there is a new โ€œdynamicโ€ keyword to request late binding).

v-table calls are neither early nor late. Instead, there is an offset to the function pointer table. The offset is fixed at compile time, but which table is selected from the function pointer depends on the type of runtime of the object (the object contains a hidden pointer to its v-table), so the final address of the function is at runtime.

EDIT to address new issues:

In (1) the whole premise is false. Functions are not stored anywhere near objects that "own" them. In fact, there is only one copy of the function for the entire program, and the object instance is passed as the hidden parameter "this", so the function knows which instance is accessing.

For (2), two possibilities are possible. Firstly, a function call is executed through reflection through MethodInfo or such. It is really late. Secondly, a function call is made through an interface or base class that the caller knows at compile time, although the general type of the object is unknown. In this case, the v-table call is used because the layout of the v-table is determined by the base class or interface, so the caller is aware of this and can predetermine the offset in the v-table.

+1
source

Source: https://habr.com/ru/post/1303711/


All Articles