首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >E2010不兼容类型,为什么?

E2010不兼容类型,为什么?
EN

Stack Overflow用户
提问于 2011-12-01 22:51:06
回答 1查看 4.5K关注 0票数 9

我得到了一个错误:

代码语言:javascript
复制
[DCC Error] JwaStrSafe.pas(2277): E2010 Incompatible types: 'PSTRSAFE_LPWSTR' and 'PSTRSAFE_LPTSTR'

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

代码语言:javascript
复制
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}

我得到了StringCchCopyExW调用的错误,参数ppszDestEnd的错误。

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

溶液

多亏了大卫的解释我才取代了

代码语言:javascript
复制
PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR;

使用

代码语言:javascript
复制
PSTRSAFE_LPTSTR = PSTRSAFE_LPWSTR;

现在,代码编译时没有错误。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-01 23:35:09

我可以在XE2中很容易地复制这一点,并且我认为它在所有其他版本中的行为都是一样的。为了使它更简单,我将其简化如下:

代码语言:javascript
复制
program PointerTypeCompatibility;
{$APPTYPE CONSOLE}
type
  A = Integer;
  B = Integer;
var
  ptA: ^A;
  ptB: ^B;
begin
  ptA := ptB;
end.

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

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

感谢肯怀特为我指出了有用的帮助主题类型兼容性和标识。相关的摘录是,在以下情况下,T1和T2类型与赋值兼容:

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

文档还指出,在以下情况下类型是类型兼容:

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

因此,这记录了观察到的行为,并将我引向这个例子:

代码语言:javascript
复制
program PointerTypeCompatibilityTake2;
{$APPTYPE CONSOLE}
{$TYPEDADDRESS OFF}
var
  P1,P2: ^Integer;
  P3: ^Integer;
begin
  P1 := P2;//compiles
  P1 := P3;//E2008 Incompatible types
end.

因此,概括地说:

  • 禁用类型检查指针时,如果指针类型相同,则指针与赋值兼容。
  • 启用类型检查指针时,如果指针指向同一类型,则指针与赋值兼容。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8349464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档