【问题标题】:function Copy() in Free PascalFree Pascal 中的函数 Copy()
【发布时间】:2012-09-22 08:36:22
【问题描述】:

Delphi 允许 Copy 函数的 3 个版本:

function CopyTest(const S: string): string;
begin
  Result:= Copy(S, 1, 5);
  Result:= Copy(S, 1);
//  Result:= Copy(S);   //  not allowed for strings, allowed for dyn arrays
end;

FreePascal 似乎只编译第一个(3-arg)版本;对于其他人,我有编译时错误

Error: Wrong number of parameters specified for call to "$fpc_ansistr_copy"

我是否缺少某些 FPC 编译器开关或 Copy 重载在 Free Pascal 中不可用?

【问题讨论】:

  • 只是添加;这是一个reference。但是,这并不意味着它是当前 RTL 代码的实际情况。
  • @TLama - 我认为 RTL 代码并不重要,编译器决定调用什么函数。 'Fpc_Ansistr_Copy' 无论如何都在 astrings.inc 中,AFAICT 没有重载。
  • +1 表示发现错误。报告为bugs.freepascal.org/view.php?id=22964(请参阅 Sertac 的答案中的 cmets)

标签: delphi copy freepascal


【解决方案1】:

“复制”节点生成器代码在 FPC 源的 pinline.pasinline_copy 函数中。仅对动态数组变体 1 和 3 有效(在变体 3 的情况下,它生成代码以将第二个和第三个参数的 -1 传递给 fpc_dynarray_copy)。对于所有其他情况(ansi 字符串、宽字符串、unicode 字符串、char(*) 和短字符串),需要 3 个参数(编译器在不检查参数的情况下生成对复制函数之一的调用(例如 astrings.pas 中的 fpc_ansistr_copy) ,因为被调用的函数没有重载或默认参数,所以需要完全匹配的参数)。不涉及任何开关/指令。

(*) 这个有点奇怪,它返回一个shortstring,要么是它自己,要么是''。

【讨论】:

  • +1 好评价。基本上三个参数字符串是原始的,动态数组版本是后来添加的。奇怪的是它从未被发现(因为它可能自 2005 年以来就是这样)。请提交错误。
  • @Marco - 谢谢!你指的是哪个bug?我虽然这一切都是按设计的。
  • Sertac 并没有要求 在哪里 提交错误,@Marco。他在问要提交哪个 错误。我在这里看不到错误。 Free Pascal 需要Copy 的字符串版本的所有三个参数,这与Delphi 的要求相同。只有 array 版本使后面的参数可选。
  • Delphi (XE) 接受字符串的第二种形式,FPC(所有当前版本,在 Delphi 模式下)不接受,原始帖子中的错误。当我写它时,我假设 Delphi 也允许字符串的第三种形式,但测试表明它不允许。也许我的评论应该是针对顶级职位的,而不是 Sertac 的。无论如何,我自己提交了错误以避免混淆,bugs.freepascal.org/view.php?id=22964
  • 奇怪,我很确定 Copy 函数的无参数版本也可以用于字符串,它是 UniqueString 过程的函数版本。但是是的,Delphi (XE) 不允许这样做。
【解决方案2】:

据我所知,Free Pascal 支持默认值参数,所以不需要重载函数。您可以编写新的Copy 函数,例如...

function Copy(const S: string; From: integer = 1; Count: integer = MaxInt): string;
begin
//There is no need to check the string length
//      if Count > Length(S) then
//        Count := Length(S);
        result := system.Copy(S, From, Count);
end;

【讨论】:

  • 我认为,如果计数超过字符串长度,您甚至不需要关心(但尚未验证这一点)。
  • 你不需要检查长度。我经常使用更长的长度。 (假设 MaxInt 不是那么大,它会导致副本中某处的 int 溢出)
  • 我不认为这回答了这个问题,因为这个问题没有问如何解决这个问题。即使不是这种情况,由于您的函数不是编译器内在函数,它需要对字符串以外的其他类型进行重载,这将再次导致此问题无法回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 2011-12-09
  • 1970-01-01
相关资源
最近更新 更多