Gu.
Gu.

Reputation: 1957

Discrepancy of types

Delphi.

Why

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;

var 
  a: myint;
  b: myNewInt;

begin
  a := b;
end;

It is compiled normally though types formally different - one is declared here, another undertakes from other module. And if

uses 
  windows;

type
   _FILETIMEA = record // Copy from windows.pas
     dwLowDateTime: DWORD;
     dwHighDateTime: DWORD;
   end;

var 
  x: _FILETIMEA;
  y: windows._FILETIME;

begin
  x := y;
end;

Will cause a compilation error (in line x:=y; [DCC Error] ... E2010 Incompatible types: 'windows._FILETIME' and '_FILETIMEA'), though type _FILETIMEA = Windows._FILETIME ?

Upvotes: 3

Views: 232

Answers (2)

Ken White
Ken White

Reputation: 125651

Because you're not doing the same thing. :) Delphi is strongly typed (there aren't many exceptions - almost everything has a specific type).

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;

There is nothing incompatible about these types. They're both the same type (integer), and support the same range of values. There's no conflict about allowing the assignment of one to the other.

// Your unit name
unit GuTypes;

Type
 _FILETIMEA = record // Copy from windows.pas
   dwLowDateTime: DWORD;
   dwHighDateTime: DWORD;
 end;

This is a new type, defined by your code (even though it's identical to the one in Windows.pas, it's not the same). It's GuTypes._FileTimeA, which is not the same as Windows._FileTimeA.

This is actually a good thing, because it allows different units to use the same typenames without conflict; you can prefix with the unit name as a "namespace" to clarify which one you mean to use. For instance, if you have yours defined in GuTypes, and Windows has one declared there, in a third unit MyAppCode, you can do this safely:

var
  GFileTime: GuTypes._FILETIMEA;
  WFileTime: Windows._FILETIMEA;

Even if one of the types changes, your code is safe from side effects, because the two types can't accidentally be interchanged.

You can typecast to force the assignment to work, but that's usually a bad idea; it defeats the whole purpose of using a strongly typed language. Typecasting tells the compiler "I'm smarter than you, and I know this is wrong but I want you to ignore it and do it anyway."

A better solution would be either to declare your variable as you did the y in your example (Windows._FILETYPEA), or to declare a compatible type (type TMyFileTimeA = Windows._FILTETIMEA;).

See the XE2 Wiki Pages on Type Compatibility and Identity. Look specifically at the Assignment Compatibility section.

Upvotes: 7

Andreas Hausladen
Andreas Hausladen

Reputation: 8141

Delphi doesn't support duck typing. You have 2 different records. They just look a like, but they are 2 different types for the compiler. If you want to assign the two variables you have to type cast them what is possible because they have the same size.

x := _FILETIMEA(y);

Upvotes: 9

Related Questions