The project below fails to run with “access violation” error. I use Delphi XE2 Update 3.
program Project1;
{$APPTYPE CONSOLE}
type
TTestClass = class
public
class procedure Test;
end;
var
TestClass: TTestClass;
class procedure TTestClass.Test;
begin
end;
begin
TestClass.Test;
end.
If i mark class procedure Test as “static”, there is no problem. Is this ‘as designed’?
P.S.: It was my mistake, shame on me.
Yes, what you’ve witnessed is correct.
Non-static class methods, just like instance methods, have a hidden
Selfparameter. For class methods, that refers to the class reference. It’s like the compiler transforms your method into this:When you call a class method on a non-class receiver (i.e., an object reference), the compiler inserts a call to
ClassTypeto fill in that parameter with the run-time type of the object, like this:The
ClassTypemethod fetches the address of the object’s VMT, but your variable doesn’t refer to any VMT. Your variable is either a null pointer or uninitialized, so attempting to dereference it to read the VMT address results in an access violation, if you’re lucky. (If you’re unlucky, it dereferences the address and the address happens to be somewhere else in your program’s address space, and the result is interpreted as a VMT pointer even though it’s not.)Call class methods on class references or valid object references only.
When you call it on a class-reference “literal” as above, the compiler already knows the value of the first parameter and transforms the call like this: