Delphi编译bug还是我的错误?

Bof*_*ofA 3 delphi

下面的项目无法以"访问冲突"错误运行.我使用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.
Run Code Online (Sandbox Code Playgroud)

如果我标记class procedure Test为"静态",则没有问题.这是'设计'吗?

PS:这是我的错,对我很羞耻.

Rob*_*edy 7

是的,你目睹的是正确的.

与实例方法一样,非静态类方法具有隐藏Self参数.对于类方法,它引用类引用.这就像编译器将您的方法转换为:

type
  TTestClassClass = class of TTestClass;

procedure TTestClass_Test(Self: TTestClassClass);
Run Code Online (Sandbox Code Playgroud)

当您在非类接收器(即对象引用)上调用类方法时,编译器会插入一个调用,ClassType以使用对象的运行时类型填充该参数,如下所示:

TTestClass_Test(TestClass.ClassType);
Run Code Online (Sandbox Code Playgroud)

ClassType方法获取对象的VMT的地址,但您的变量不引用任何VMT.您的变量是空指针或未初始化,因此如果您很幸运,尝试取消引用它以读取VMT地址会导致访问冲突.(如果你运气不好,它会取消引用地址,而地址恰好位于程序地址空间的其他地方,并且结果被解释为VMT指针,即使它不是.)

仅对类引用或有效对象引用调用类方法.

TTestClass.Test;
Run Code Online (Sandbox Code Playgroud)

当您在类引用"文字"上调用它时,编译器已经知道第一个参数的值并转换调用,如下所示:

TTestClass_Test(TTestClass);
Run Code Online (Sandbox Code Playgroud)