Typically neither. Note this is very much implementation specific - what I describe below is typical but different processors may do things differently.
Note there are no procedure pointers in your example. The type class_type
has a binding. If the class_type
had a procedure pointer, things are different.
Typical implementation for bindings is that the compiler creates a table of machine level pointers, with one entry for each specific binding, with the pointer pointing at the code for the procedure. A table (sometimes known as a "vtable", from the similar technique used for virtual member functions in C++ and similar languages) is created for each type in the program.
For polymorphic objects (things declared with CLASS
), the compiler then creates a descriptor that has a machine level pointer to the relevant table for the dynamic (runtime) type of the object. This pointer effectively indicates the dynamic type of the object and may be used in constructs such as SELECT TYPE
and invocations of things like SAME_TYPE_AS
. If you have a polymorphic array the compiler will initially typically only create one descriptor for the entire array, as individual elements in the array must all have the same dynamic type.
When you call a binding on a polymorphic object, the compiler follows the pointer to the vtable, then looks up the relevant pointer to the procedure binding.
No such descriptor or pointer dereferencing is required for non-polymorphic objects (things declared with TYPE) as the dynamic and declared type are always the same, the compiler knows what the declared type is and the compiler knows, at compile time, which procedure will be called.
If you have a procedure call where a non-polymorphic actual argument is associated with a polymorphic dummy argument, then the compiler will typically create the necessary descriptor as part of making the procedure call. Similarly for passing a polymorphic array element to a procedure taking a polymorphic scalar.
The main program of your code contains no polymorphic entities, and you call no procedures, so there may not be any machine pointers back to the vtable.
Procedure pointer components (components declared PROCEDURE(xxx), POINTER :: yyy
before the CONTAINS of the type declaration) can be different for every object (including being different for every element in an array). In that case typical implementation is to store a machine level pointer to the code for the relevant procedure (or a null pointer if the procedure pointer component has not been associated).