Parameters 关于如何正确转换变量记录函数参数的老派Pascal问题

Parameters 关于如何正确转换变量记录函数参数的老派Pascal问题,parameters,casting,pascal,variant,Parameters,Casting,Pascal,Variant,我正在尝试创建一个带有变量记录类型参数的函数,该参数允许内联转换或赋值,例如: type rectype = ( VT_INT, VT_CHAR, VT_BOOL ); rec = record case t : rectype of VT_INT : ( i : integer ); VT_CHAR : ( c : char ); VT_BOOL : ( b : boolean ); end; proc

我正在尝试创建一个带有变量记录类型参数的函数,该参数允许内联转换或赋值,例如:

type rectype = ( VT_INT, VT_CHAR, VT_BOOL );
     rec = record
       case t : rectype of
         VT_INT  : ( i : integer );
         VT_CHAR : ( c : char );
         VT_BOOL : ( b : boolean );
     end;

procedure handler( r : rec );
begin
  case r.t of
    VT_INT  : { do something with r.i }
    VT_CHAR : { do something with r.c }
    VT_BOOL : { do something with r.b }
  end;
end;
 r.t := VT_INT;
 r.i := 42;
 handler( r );
现在,只要您花时间手动设置变量,上述“工作”就可以了,如下所示:

type rectype = ( VT_INT, VT_CHAR, VT_BOOL );
     rec = record
       case t : rectype of
         VT_INT  : ( i : integer );
         VT_CHAR : ( c : char );
         VT_BOOL : ( b : boolean );
     end;

procedure handler( r : rec );
begin
  case r.t of
    VT_INT  : { do something with r.i }
    VT_CHAR : { do something with r.c }
    VT_BOOL : { do something with r.b }
  end;
end;
 r.t := VT_INT;
 r.i := 42;
 handler( r );
但是,我想稍微滥用一下打字系统,并尝试以内联方式(稍后我将解释原因),大致如下:

 handler( rec( VT_INT, 42 ) );
助手函数也可以,我已经尝试了几种不同的方法来实现这一点,可以在这里看到(为了本文的简洁):

现在,出于这个原因:我正在开发,并且确实发布了一个单元测试套件,其目标是与Pascal本身一样可移植(在FreePascal和Turbo Pascal 7下构建(是的,真的))。我已经公开发布了开源软件(还不能链接,没有足够的rep),其中包括不同类型的不同函数:isI()、isR()、isS()、isP()、isC(),等等。这重复了很多代码,我知道有更好的方法来实现这一点。我相信FPC和Delphi支持一种变体类型,我可以通过IFDEF指令在这些平台上使用它,但真正的关键是TP7,出于淫秽的原因,我仍然希望支持它

每个函数调用4行来设置记录的原因实际上是不可行的,因为这是面向用户的API,进行复杂的测试只意味着没有人会这么做。使用当前API的测试集非常简单,只需调用一个函数即可执行每个测试,我只希望能够将所有特定于类型的函数转换为如下内容:

is( VT_INT, SomeIntFunc( v ), 42, 'Test Name' );
我愿意尽最大努力避免在TP7下键入,包括自己在汇编中操作堆栈等。但我希望使用我不熟悉的语法修改版本能够完成这项工作


所以,老式的Pascal程序员(我知道一定有一些),有什么建议吗?

免费的Pascal没有问题,因为它支持Delphi构造,如(自定义)变量、常量接口数组和其他处理运行时类型的技巧(只要限制在可监督的数量)。最近的Delphi和FPC支持泛型,您可能要用它来复制“boost”

然而,在旧学校里做这件事是困难的。它几乎没有非类型化(或更好的:运行时类型化)功能

我唯一能想到的就是

 procedure rec(vartype:Ttypeofvar;var value):tvariantrecord;
 begin
   rec.t:=vartype
   case vartype of 
      vt_int: move (value,@rec.i,sizeof(integer));
      ..
      ..
 end;
这是一个工作环境,但不是类型安全的,因为可以通过rec(varint,“something double”)。除了VAR形式参数外,TP没有太多的工作要做


在这一点上,你真的必须问问自己,削弱你的TP7框架是否真的值得。它已经死了16年了。让它平静地腐烂吧。

当前的API,具有不同类型的函数,如果is()和isnt()可以在这里看到非工作示例:在第190-334行中,您可以看到所有的重复;第340-363行显示了将它们合并为一的初步尝试。嗨,马可!感谢您在FPC上的工作:-)我考虑了var X;非类型变量参数选项;问题是,您不能将立即数(例如42)放入函数调用中,因为它必须通过引用传递。关于TP,你说得很好,但自从我开始测试一些旧的TP软件以来,我一直希望有一个解决办法。尽管如此,自从我发布了这篇文章,我已经搜索了Usenet和SWAG档案,看起来这在编译器中是完全不可能的。啊好,;我认为目前的API已经足够了。谢谢你的回复。