Delphi has long supported a few basic numeric types and I was wondering how they are related to each other.
In Delphi 2007 I found these declarations (some are conflicting, some are mere aliasses) :
Types.pas:
DWORD = LongWord;
Largeint = Int64;
getmem.inc:
DWORD = Integer;
Windows.pas:
DWORD = Types.DWORD;
SHORT = Smallint;
UINT = LongWord;
ULONG = Cardinal;
LONGLONG = Int64;
TLargeInteger = Int64;
ULONGLONG = UInt64;
This leads me into thinking the base signed numeric types are SmallInt, Integer and Int64. Unsigned, there's Byte, WORD and UInt64. But what is the difference between Cardinal and LongWord? (By the way, what's the original and intended casing for these types?)
And is there a type for signed 8 bit integers (Int8)?
// Int8 = ?unknown?;
UInt8 = Byte;
Int16 = SmallInt;
UInt16 = Word;
Int32 = Integer;
UInt32 = LongWord;
// Int64 already exists
// UInt64 already exists
Lastly, how should I define Int and UInt, especially with regard to C/C++ compatibility and a future switch to other platforms (possibly also 64 bit)? (A related question is, of course, how will the various numeric types be defined in 64-bit Delphi?)
First, let's define a type. In Delphi, like in C, VB and unlike PHP, Python or other modern languages, a variable is typed and can only contain values of this type. To make it simple, a type is a variable attribute.
DELPHI: Numbers Variables are declared as integers if they use whole numbers (for example 23 or 765) and real if they have decimal fractions (for example 2.63 or 0.46544). Apart from the data type Integer other related types include (ranges included):
The Integer type is the basic integer type. The size of an integer can vary with different versions of Delphi. Currently, Integer is a 32-bit type, but future versions might change the size. Delphi defines a number of integer types of varying ranges. The predefined integer types are shown in the following table.
The Cardinal type is an unsigned integer subrange whose size is the natural size of an integer. In Delphi 5, the size is 32 bits, but in future versions of Delphi, it might be larger. Use LongWord for an unsigned integer type that must be 32 bits, regardless of the natural size of an integer.
The signed one-byte integer type is ShortInt
. You can remember its size by the fact that it's not the same size as usual C implementations of the short
type.
As for capitalization, capitalize the first letter. The documentation tends to leave the "int" part at the end lowercase, as in Longint, but I think it's more common to capitalize it. Don't write the types in all capitals unless you're using Platform SDK types and you want your code to show its C roots; otherwise I'd just write Word
and DWord
, Long
and ULong
, etc.)
Delphi 2009, perhaps earlier, already defines types like Int8
and UInt32
. As for how to define Int
and UInt
, I'd say don't. The language you're using already defines Integer
and Cardinal
; don't introduce new type names when you don't have to. Keep the names you already have, and then everyone else will know what you're talking about. (Besides, Int
is already a function in the System unit.)
Use Use Cardinal
when you want an unsigned type and don't care about its size; use LongWord
when the variable must be exactly four bytes. Likewise for Integer
and LongInt
.Cardinal
when you want a four-byte unsigned type; use LongWord
when you want a generic unsigned type and don't care about the size. Likewise for Integer
and LongInt
, nowadays. If you're writing 16-bit code, use LongInt
when you need four bytes and use Integer
when you don't care about the size; Cardinal
and LongWord
didn't exist in Delphi's and Turbo Pascal's 16-bit days.
The common wisdom for years had been that Integer
and Cardinal
would become 64-bit types on a 64-bit compiler, but that is apparently not the case. Instead, they will remain 32-bit types, just as their counterparts in Microsoft C++ do. Furthermore, there will be a new type, NativeInt
, which will be a 64-bit type in a 64-bit compiler. The LongInt
and LongWord
types will become 64-bit types because they have always been the same size as the Pointer
type, which was 32 bits even in 16-bit times.
UInt8 = Byte
Int8 = ShortInt
UInt16 = Word
Int16 = SmallInt
UInt32 = LongWord
Int32 = LongInt
UInt64 = UInt64
Int64 = Int64
int = Integer
uint = Cardinal
NativeInt (generic, depends on CPU register size)
NativeUInt (generic, depends on CPU register size)
Cardinal and Integer are generic types. For 16 bit they were 16 byte large and for 32 bit they are 32 bit large. For 64 bit the Windows 64bit platform (LLP64) defines them as 32 bit. The new NativeInt and NativeUInt types are now the CPU register sized types.
Cardinal and Integer are aliases.
Cardinal ==> LongWord (unsigned)
Integer ==> LongInt (signed)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With