Having started with Delphi before the Cardinal type was available (Or has it always? I can't remember.) I routinely declare 32 bit unsigned variables as LongWord.

Having started with Delphi before the Cardinal type was available (Or has it always? I can't remember.) I routinely declare 32 bit unsigned variables as LongWord.

What do you use?

Comments

  1. LongWord and Cardinal are 64 bit on some platform(s). UInt32 should be platform independent.

    ReplyDelete
  2. I use Cardinal (as in "the biggest unsigned int around")

    ReplyDelete
  3. I used to use Byte, Word, Longword, but now prefer Int8, UInt8, Int16, UInt16, etc. because these names are unambiguous (unlike e.g. Shortint, which is signed 8 bit, while in many other languages short int is 16 bit) and never bound to change.

    ReplyDelete
  4. Sergey Kasandrov exactly. That was the reason I stopped using these names: that they are not fixed size anymore. I doubt they‘ll ever make, say, UInt32 a 64 bit type.

    ReplyDelete
  5. you should use Assert(SizeOf(XXX) = 4) (replace XXX with what you want)

    ReplyDelete
  6. Except for byte (and Windows API translations) I always use integer names with bit number.

    ReplyDelete
  7. Does it need to be 32-bit specifically, or just native-bitness? I like NativeInt and NativeUInt.

    ReplyDelete
  8. Sergey Kasandrov On which platform is Cardinal not 32bit?

    ReplyDelete
  9. David Millington If you use it for permanent storage then it is important to have same bitness across platforms.

    ReplyDelete
  10. According to

    docwiki.embarcadero.com - 64-bit Windows Data Types Compared to 32-bit Windows Data Types - RAD Studio

    LongWord is always 32 bits, as is Cardinal.

    Int64 / UInt64 are always 64 bits.

    NativeInt / NativeUInt are 32 or 64 bits, depending on the platform (and after the bug with their declaration was fixed in XE2).

    ReplyDelete
  11. David Millington I am specifically talking about 32 bits unsigned integer. This is what I was looking at when I asked the question. It's a field in a binary file header so it has to be exactly that size.

    ReplyDelete
  12. Thomas Mueller Ok - makes sense if it has to be 32 specifically. I asked because the other two types "float" (no pun intended) and that can be ideal depending on the circumstances. Yes, yours isn't one of them :)

    ReplyDelete
  13. Thomas Mueller In some of the non-Windows compilers, LongWord is 64 bits.

    ReplyDelete
  14. David Millington according to

    docwiki.embarcadero.com - System.LongWord - RAD Studio API Documentation

    which Stefan Glienke just cited, LongWord is 64 bits on 64 bits Posix platforms (Linux and IOS).

    This is getting confusing. Maybe I should really stop using LongWord then.

    ReplyDelete
  15. Thomas Mueller for a long time I liked to translate C ++ APIs full of #ifdef in Pascal with well known types ... today it is also badly done under Delphi and C ++ :(

    ReplyDelete
  16. The types with numbers indicating bitness are reliable, eg, UInt64. Those will not change.

    ReplyDelete
  17. This discussion shows me that the whole system is sick. Niklaus Wirth was right. Too much complexity is unmanageable.

    ReplyDelete
  18. If I remember right, the Cardinal type was introduced when Integer type became 32-bit; Cardinal was unsigned Integer, and since Integer became platform-dependent (16 bit on 16-bit platform, 32 bit on 32-bit platform) it suggested that Cardinal and Integer are both now platform-dependent types; Cardinal just was not defined on 16-bits. But it turned out that LongInt and LongWord became platform-dependent types, quite unexpectedly, while Integer and Cardinal are now platform-independent in docs. But Integer was not platform-independent, and I have no reason to believe that Integer will stay platform-independent in future; same with Cardinal.

    ReplyDelete
  19. Lars Fosdal Cardinal isn't the biggest unsigned unteger

    ReplyDelete
  20. Sergey Kasandrov if I remember well, Integer and Cardinal follows Microsoft convention for Int and dword...not a great idea when Delphi had become multiplatform.

    ReplyDelete
  21. Ralf Stocker "This discussion shows me that the whole system is sick. " Just use bigints for everything and all the complexity goes away. :-)

    ReplyDelete
  22. David Heffernan "Cardinal isn't the biggest unsigned unteger".

    What comes next? Pope? :-)

    ReplyDelete
  23. Brian Ford Not Cardinal, but Longint and Longword, which have been considered as fixed size for a very long time, are not fixed size anymore, e.g. Longword: http://docwiki.embarcadero.com/Libraries/Berlin/en/System.LongWord .

    ReplyDelete
  24. David Millington Exactly. When it was announced that Longint and Longword were not fixed size anymore, I stopped using Longword, Word and similar types for fixed size purposes. The (U)IntXX names are more reliable.

    ReplyDelete
  25. Nothing is 100% reliable now. Example: for compatibility sake, OpenSSL devs kept the name 'libeay32.dll' on Win64 platform (until finally they changed the name to 'libcrypto.dll' to avoid confusion) :)

    ReplyDelete
  26. You've probably all already seen it, but this doc page is a useful guide on platform-dependent and platform-independent integer types. I think we could expand it though. http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Simple_Types_(Delphi)#Integer_Types

    ReplyDelete
  27. Uwe Raabe Is anybody uses FixedUInt? The name suggests existence of FloatUInt. :)

    ReplyDelete
  28. David Millington I think you should remove the "alias" column from the platform dependent table. It just adds to the confusion.

    ReplyDelete
  29. David Millington There is a mistake there. It says "Platform-independent integer types always have the same size, regardless of what platform you use. Platform-independent integer types include ShortInt, SmallInt, LongInt, Integer, Int64, Byte, Word, LongWord, Cardinal, and UInt64.". But Longint and Longword are platform dependent these days, and Integer was platform dependent too (in 16 bit Delphi and TP, it was 16 bit).

    ReplyDelete
  30. Rudy Velthuis I doubt that Embarcadero cares about Integer having been 16 bit in TP and Delphi 1. But it's good to be remembered of that once in a while since I still have to maintain a few DOS programs in Borland Pascal.

    ReplyDelete
  31. Sergey Kasandrov user32.dll and kernel32.dll can be 64 bit DLLs too, in Win64.

    ReplyDelete
  32. Arthur Hoornweg It is always best to use the types that Windows API functions declare, i.e. instead of using Longword or Cardinal, use DWORD where that is declared, and LPARAM or WPARAM where that is declared in the documentation, etc. That ensures you have the right type and size for any platform, fixed size or not.

    ReplyDelete
  33. Thomas Mueller They may not care much about D1 or TP anymore, but that sentence is simply wrong and should be corrected, IMO.

    ReplyDelete
  34. Brian Ford FWIW, just took a look in the Delphi 1 Object Pascal Language Guide and in table 3-2, they mention Integer and Cardinal as generic types (as opposed to fixed size fundamental types). `Cardinal` is listed as 0..65535 in 16 bit and in table 3-3, they even mention that in 32 bit Delphi (which was not even released yet!) Cardinal was to be 32 bit.

    So Cardinal did exist in Delphi 1, before the 32 bit versions came around. And it was 16 bit.

    My memory did not fail me, after all. The Delphi User Guide does not mention Cardinal, and that confused me.

    ReplyDelete
  35. Rudy Velthuis My thoughts exactly. I always use the WinAPI type names when calling the Windows API.

    But I have always liked the names "Dword" and "Qword" for unsigned variables simply because the size is clear (WORD being 16 bits).


    For data exchange in binary form, one needs to avoid all "fuzzy" integer types that are 32-bit on some systems and 64-bit on others, because if you create records that contain such types and write these to disk, the data will suddenly become binary incompatible if the software is compiled for another platform (and endianness is another potential issue, I know).

    IMO there are too many obsolete and dubious integer types.

    For example, "Longint" is a legacy type from the 16-bit era where a "normal" integer was too small to hold decently large numbers. It would have been much cleaner to make this data type obsolete in Delphi 2 and forget it ever existed.

    Fixedint and Fixeduint appear to be merely aliases for Integer and Cardinal. A quick grep shows me that Embarcadero hardly ever uses these data types in the RTL/VCL source code. Their very existence only sows doubt about the "fixedness" of the existing integer/cardinal types. Why not just keep the language clean ?

    ReplyDelete
  36. Arthur Hoornweg Back in the Delphi 2 days, there was a lot of code written for Turbo Pascal that used LongInt. Simply forgetting that type would have meant that porting that code to Delphi takes a lot more work than keeping the type around. I still maintain some Turbo Pascal code and we only ported most of it to Delphi with Delphi 2007 about 5 years ago. So, IMHO there still is a use case for keeping LongInt and LongWord around. They shouldn't have changed them to anything but 32 bits though.
    I agree bout Fixedint and Fixeduint though. The only reason to have them is if you have code that already used them. And that would be my guess where they came from: Embarcadero bought some code and could not be bothered to convert it to use sane integer types.

    ReplyDelete
  37. I have invested many years in TP code as well, even converted a lot of code to Delphi, and the differences in object model between TP and Delphi were much more work to fix than a simple search and replace from Longint to Integer would ever be.

    But hey, Turbo Pascal is not Object Pascal. Keeping variable types just for the sake of compatibility with a predecessor language designed for DOS and CP/M is a bit far fetched.

    Having said that, I really liked Turbo Pascal. I've worked with every version from 3.01 to 7. And for many years I've had my Delphi set to a yellow font on a blue background!

    ReplyDelete
  38. Arthur Hoornweg the code I was talking about contained a lot of (complex) calculations. And btw.: the old object model was still working in Delphi for quite a while. Not sure what the status is today.

    ReplyDelete
  39. Thomas Mueller it still does, mostly. But it has some bugs and there is not much hope fixing them is high on their priority list.

    ReplyDelete

Post a Comment