且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么格式崩溃时除了“%s”之外的任何东西与Variant一起使用?

更新时间:2023-02-19 21:22:34

这是功能的限制。在Delphi XE中,SysUtils的相关部分从10870行开始,如下所示:

  @CvtVariant:
CMP CL,'S'
JNE @CvtError

这是为任何变体参数调用的。 CL寄存器具有该特定参数的格式字符串所需的类型,对于与S不同的任何异常,


I'm working with the SysUtils.Format function and variant values, and I found that this function only works if the format string is %s. I checked the documentation about the Format function but there does not exist any reference to how variant values are treated.

Consider this simple application:

{$APPTYPE CONSOLE}

uses
  Variants,
  SysUtils;

procedure TestFormat;
var
  v : Variant;
begin
  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:='100';
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %d',[v]));//raise a EConvertError exception EConvertError: Format '%d' invalid or incompatible with argument
end;


begin
  try
     TestFormat;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

Is this a bug or a simple limitation of this function?

I've checked this behavior in Delphi 5, Delphi 2007 and Delphi XE.

It is a limitation of the function. In Delphi XE, the relevant part in SysUtils starts at line 10870, which looks like this:

@CvtVariant:
        CMP     CL,'S'
        JNE     @CvtError

This is called for any variant argument. The CL register have the type required by the format string for that particular argument, for anything different than 'S', the exception is raised.