E2010 Incompatible types, why?

I get this error:

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

Below is the corresponding piece of code from JwaStrSafe.pas (from Jedi Api), I am compiling with a specific UNICODE character:

 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} 

I get an error when calling StringCchCopyExW on the ppszDestEnd parameter.

Looking at the type definition, I understand that PSTRSAFE_LPTSTR is a pointer type for STRSAFE_LPTSTR, which is just an alias for STRSAFE_LPWSTR, why are PSTRSAFE_LPTSTR and PSTRSAFE_LPWSTR incompatible?

Decision
Thanks to David's explanation, I replaced

 PSTRSAFE_LPTSTR = ^STRSAFE_LPTSTR; 

from

 PSTRSAFE_LPTSTR = PSTRSAFE_LPWSTR; 

Now the code compiles without errors.

thanks

+7
source share
1 answer

I can reproduce this quite easily in XE2, and I believe that it will behave the same in all other versions. To make this easier, I shortened it to:

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

It also gives the E2010. However, if you enable the type-pointers option, the code will compile successfully. In fact, the documentation for these compiler options states:

In state {$ T-}, different types of pointers other than a pointer are incompatible (even if they are pointers to the same type). In state {$ T +}, pointers to the same type are compatible.


Thanks to Ken White for pointing me to a helpful help topic Type Compatibility and Identification . Suitable extracts are that types T1 and T2 are compatible with the intended use if:

T1 and T2 are compatible pointer types.

The documentation also states that types are types compatible if:

Both types are (typed) pointers to the same type and the compiler directive {$ T +} is valid.

So this documents the observed behavior and leads me to this example:

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

So, we summarize:

  • If pointers marked with a type are disabled, pointers are compatible with the destination if the pointers are of the same type.
  • When type-checked pointers are turned on, pointers are compatible with the destination if the pointers point to the same type.

I must admit that I am not aware of the history and reasoning for setting the type pointer, so I cannot offer any explanation why the compiler is what it is.

+3
source

All Articles