1) virtual is correct according to doc (surprising, but yes)
http://www.freepascal.org/docs-html/ref/refsu26.html#x68-770005.5.2-------
http://www.freepascal.org/docs-html/ref/refse26.html#x62-690005.1Objects should be treated as a special kind of record. The record contains all the fields that are declared in the objects definition, and pointers to the methods that are associated to the objects’ type.
My understanding.
The object is a record. That also implies all data is passed as COPY, not as reference)
The param to Caller is a record of type delegate. (When this is compiled, there is no knowledge if other units have inherited objects, that have more fields / So it can only hold the fields of delegate)
When caller is called, only the "common" part (only delegate) is passed. "n" is not passed (it could not be stored in a delegate.
As for the virtual methods: Since both (delegate and delegate2) have a VMT, the correct VMT is passed, and dellegate2.p is called from caller.
Therefore you are lucky it is just wrong data. IT could be an access violation. You are accessing data outside of the object.
---
Why object, why not class?