Difference between LongInt and Integer, LongWord and Cardinal

  • Delphi Integer is the underlying platform's C++ int.
  • Delphi LongInt is the underlying platform's C++ long int.
  • Delphi Cardinal is the underlying platform's C++ unsigned int.
  • Delphi LongWord is the underlying platform's C++ unsigned long int.

All four of these types are platform dependent.

On all supported platforms at the time of writing, Integer and Cardinal are 32 bit types. The types are platform dependent, it so happens that on all supported platforms the types are the same size.

On 64 bit *nix platforms, LongInt and LongWord are 64 bit types. On all other supported platforms, at the time of writing, the types are 32 bit types.

The key point is that these types are all platform dependent.

DWORD is a type alias used by the Windows API. Use it only when using that API.

Should you use Integer or LongInt? That depends on your use. As a rule, for interop use whichever type matches the C++ code. Otherwise, for most uses Integer is appropriate. Of course, this is a generic answer to your general question.


In short: Longint and Longword are fixed size integers, the former signed, the latter unsigned, and both usually 32 bits in size. Their size is platform-dependent in XE8, but fixed size (32 bits) in XE7 and earlier versions.

Integer and Cardinal are not fixed size. They are so called "generic" integers (do not confuse this with generics, which is a different pair of shoes), i.e. they should preferrably be used when an integral type is required, regardless of the size. Depending on version and platform, the size of Integer and Cardinal may differ. Currently, they are the same size and type as Longint and Longword.

The sizes of the fixed size types don't differ between versions or platforms. You should use these types where you must interface with code or data from other sources than your own program, in other words, where exact binary compatibility is important, e.g. when calling API functions. Hence the use of types like DWORD, etc.

Note that current versions have aliases for types like Byte or Smallint. They are Int8, UInt8, Int16, UInt16, etc... up to UInt64. ISTM that these names are easier to remember than e.g. "Smallint" (16 bit signed) or "Shortint" (8 bit signed).

So use Integer and Cardinal whenever that is possible, since these are probably the ideal types for the platform and version. Use the fixed size types like Byte, Smallint, Longint or UInt64, just to name a few, when exact binary compatiblity with other data is required.

Update

Since there has been some confusion (see link near the top), and since nowadays not Longint and Longword are considered fixed size platform independent anymore, but, weirdly enough, Integer and Cardinal are considered fixed size, I more and more tend to use the (U)IntXX versions like UInt16 or Int32. One exception is my use of Byte, which I can't imagine ever changing its size (of 1).

And of course I will use Integer and Cardinal for anything that needs an integral type for which the size is not so important, e.g. for loop counters, etc.

Tags:

Delphi