为什么以下字符指针类型被认为是不兼容的?

时间:2012-01-12 05:17:30

标签: delphi types

请考虑以下代码段:

procedure TForm1.FormCreate(Sender: TObject);
  {$REGION 'Sealed declarations'}
  type WCh = WideChar; // (1)
  type Str = ^WCh;     // (2)
  { this routine accepts character pointer }
  procedure Baz(Param: Str);
  begin
  end;
  {$ENDREGION}
  { this one too, but character pointer type used directly }
  procedure Bar(Param: PWideChar);
  begin
  end;
  { this constant should be compatible with strings and character pointers }
  const FOO = 'FOO';
begin
  Bar(FOO);  // compiles!
  Baz(FOO);  // BAH! E2010 Incompatible types: 'Str' and 'string'
end;

如何解决此问题,同时保留声明中的结构化输入以及使用中的清晰度和可读性(我希望没有重大的类型转换)?

NB:通过“密封声明”,我的意思是。除非绝对必要,否则我宁愿不修改它。

stringPChar之间转换的内部处理因版本而异,因此环境可能很重要 - 我在Delphi XE中遇到此问题。

2 个答案:

答案 0 :(得分:4)

正如Rob Kennedy在评论中正确注意到的那样,问题是从字符串 literal 转换而不是字符串 type

简化编码Delphi允许从字符串文字隐式转换为PChar类型和PChar别名。

为避免类型转换,您可以使用

  type Str = PWideChar;

或使用distict类型

  type Str = type PWideChar;

我没有注意到字符串文字有任何区别 - >在Unicode Delphi版本(2009及以上版本)中的PWideChar隐式转换。

答案 1 :(得分:1)

您的WCh = WideChar定义为WideChar创建了一个类型别名 - 他们有类型标识 - 但后续Str = ^WCh定义 >为PWideChar创建一个类型别名。当$T+生效时,它们兼容兼容并且可以兼容,但在这种情况下,这些都不够好。它们仍然是不同的类型。

FOO常量是字符串文字documentation for assignment compatibility表示可以为字符串文字分配的类型:" PAnsiChar,PWideChar,PChar或任何字符串类型。" Str不是字符串类型。它是指针类型,但它不是PWideChar,尽管它们的定义有多么类似。

字符串文字的类型根据上下文进行调整。当编译器需要PWideChar时,字符串文字是PWideChar。当编译器需要AnsiString时,它就是AnsiString。 (如果编译器需要这两种类型,那么文字将以两种方式存储在程序中。)字符串文字不能分配给Str类型,因此,根据错误消息,编译器显然选择string作为该情况下字符串文字的类型。您可以将其类型转换为其他内置类型之一,但更好的解决方案是避免使用自定义字符指针类。