繁体   English   中英

E2010不兼容类型,为什么?

[英]E2010 Incompatible Types, why?

我收到此错误:

[DCC Error] JwaStrSafe.pas(2277): E2010 Incompatible types: 'PSTRSAFE_LPWSTR' and 'PSTRSAFE_LPTSTR'

以下是来自JwaStrSafe.pas(来自Jedi Api)的代码的相关部分,我正在使用定义的UNICODE符号进行编译:

type

STRSAFE_LPWSTR = PWIDECHAR;
PSTRSAFE_LPWSTR = ^STRSAFE_LPWSTR;

{$IFDEF UNICODE}
  STRSAFE_LPTSTR = STRSAFE_LPWSTR;
  PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR;
{$ELSE}
  ...
{$ENDIF}

...
//function declaration
function StringCchCopyExW(
  {__out_ecount(cchDest)}pszDest : STRSAFE_LPWSTR;
  {__in}cchDest : size_t;
  {__in}const pszSrc : STRSAFE_LPCWSTR;
  {__deref_opt_out_ecount(pcchRemaining^)}ppszDestEnd : PSTRSAFE_LPWSTR;
  {__out_opt}pcchRemaining : PSize_t;
  {__in}dwFlags : Cardinal) : HRESULT; stdcall; forward; external;

...
//var passed to function
ppszDestEnd : PSTRSAFE_LPTSTR;

...

{$IFDEF UNICODE}
  result := StringCchCopyExW(pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
{$ELSE}
  result := StringCchCopyExA(pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags);
{$ENDIF}

在参数ppszDestEnd上调用StringCchCopyExW时出现错误。

查看类型定义,我知道PSTRSAFE_LPTSTR是指向STRSAFE_LPTSTR的指针类型,这只是STRSAFE_LPWSTR的别名,为什么PSTRSAFE_LPTSTR和PSTRSAFE_LPWSTR不兼容?


多亏了大卫的解释,我才换下

PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR;

PSTRSAFE_LPTSTR = PSTRSAFE_LPWSTR;

现在,代码可以正确编译。

谢谢

我可以很容易地在XE2中重现它,并且我想它在所有其他版本中的表现都一样。 为了简化起见,我将其简化为:

program PointerTypeCompatibility;
{$APPTYPE CONSOLE}
type
  A = Integer;
  B = Integer;
var
  ptA: ^A;
  ptB: ^B;
begin
  ptA := ptB;
end.

这也会产生E2010。 但是,如果启用了类型检查的指针选项,则代码将成功编译。 实际上,该编译器选项的文档指出:

在{$ T-}状态下,除Pointer以外,其他不同的指针类型不兼容(即使它们是指向同一类型的指针)。 在{$ T +}状态下,指向相同类型的指针是兼容的。


感谢Ken White向我指出了有用的帮助主题“ 类型兼容性和标识” 相关的摘录是,如果满足以下条件,则类型T1和T2是赋值兼容的

T1和T2是兼容的指针类型。

该文档还指出在以下情况下类型是类型兼容的

两种类型都是指向相同类型的(类型化)指针,并且{$ T +}编译器指令有效。

因此,这记录了观察到的行为,并引导我到此示例:

program PointerTypeCompatibilityTake2;
{$APPTYPE CONSOLE}
{$TYPEDADDRESS OFF}
var
  P1,P2: ^Integer;
  P3: ^Integer;
begin
  P1 := P2;//compiles
  P1 := P3;//E2008 Incompatible types
end.

因此,总结一下:

  • 禁用类型检查的指针时,如果指针属于同一类型,则指针是分配兼容的。
  • 启用类型检查的指针后,如果指针指向同一类型,则指针是分配兼容的。

我不得不承认对类型检查指针设置背后的历史和推理一无所知,因此我无法提供任何解释说明为什么编译器是这样的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM