Reputation: 1957
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
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
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