未记录的内部例程

Undocumented intrinsic routines

Delphi 有这个列表:Delphi Intrinsic Routines
但这份清单并不完整。

这 7 个未记录的内部函数是什么,从什么时候开始,它们的用途是什么?

我知道以下未记录的内部函数。

Delphi 2007: here and Hallvard's blog:

默认

function Default(T: Typeidentifier): value of T;     

Returns类型标识符的零表示T

解释了 XE7 中引入的以下内在函数 in the XE7 beta blog and by Stefan Glienke

IsManagedType

function IsManagedType(T: TypeIdentifier): Boolean;   

如果 Tinterfacestringdynamic array 或包含此类的记录,则为真。包含托管类型的 class 将 return 为假。

在 XE6 及更早版本中,您必须使用 System.Rtti.IsManaged(TypeInfo(T))

HasWeakRef

function HasWeakRef(T: TypeIdentifier): Boolean;    

如果 T 已被注释为 [weak],则为真。编译器保留了一个 [weak] 引用列表。您不能对这些类型使用 move 和其他技巧,因为那样会阻止更新弱列表。

在 XE6 及更早版本中,您必须使用 System.TypInfo.HasWeakRef(TypeInfo(T))

GetTypeKind

function GetTypeKind(T: TypeIdentifier): TTypeKind;   

PTypeInfo(System.TypeInfo(T))^.Kind; 做同样的事情,但是因为它是一个编译器内在函数,所以该函数在编译时解析,并且计算结果为 false 的条件代码将被编译器剥离。

IsConstValue

function IsConstValue(const Value): Boolean;          

如果值是常量则为真,否则为假。
这有助于编译器消除死代码,因为该函数是在编译时求值的。
这仅在内联函数中有用,它允许生成更短的代码。

类型信息

function TypeInfo(T: typeindentifier): PTypeInfo;

这个函数本身并不是没有记录的,但是没有记录的是它是自 XE7 以来的一个内部函数。
这意味着如果 T 不是字节,代码段 if TypeInfo(T) = TypeInfo(byte) then ... 不会生成任何代码,并且测试将在编译时解析。
但是,编译时解析仅适用于通用例程,并且仅在执行 if (TypeInfo(T) = TypeInfo(sometype) 测试时有效。
测试 if TypeInfo(byte) = TypeInfo(smallint) then 不会被淘汰,即使它总是评估为 false。
TypeInfo(T).

的其他用途也没有

返回地址

以下与 raise exception at returnaddress 结构一起使用。

function ReturnAddress(Expression): pointer;          //Delphi ?
function AddressOfReturnAddress(Expression): pointer; //Delphi ?

据我所知,您不能直接从用户代码中调用它们。

IsConstValue

的例子

type
   TFlavor = (Tasty, Nasty);
   TIntegerHelper = record helper for integer
     function GetSomething(Flavor: TFlavor): TPoint; inline;
   private
     function GetTastyPoint: TPoint;
     function GetNastyPoint: TPoint;
   end;
 
 function TIntegerHelper.GetSomething(Flavor: TFlavor): TPoint;
 begin
   if IsConstValue(Flavor) then begin
     if Flavor = Tasty then Result:= Self.GetTastyPoint
     else Result:= Self.GetNastyPoint;
   end else begin
     Assert(1=0, 'This function can only be called with constant parameters');
   end;
 end; 

procedure Test;
var
  pt: TPoint;
begin
  pt:= 100000.GetSomething(Tasty); 
此调用将被转换为 GetTastyPoint 并且 if/then 序列将被链接器消除。