3

I have a program here which was working fine in Delphi 3 that I compiled and tested on Turbo Delphi 2006 and found a problem. The problem is this: I was using "cardinal" data types as an index for something. It worked in Delphi 3, but I found values were greater than they should be in the Turbo Delphi 2006 compiled version by about 128-256 or so depending on the specific data. Changing these data types to "longint" fixed the problem so the program worked correctly with both compilers.

The question: Why is this?

My understanding was that Cardinal data types were just typical unsigned integer data. This is consistent with the application of them in this program, especially proved by the fact that the Delphi 3 compilation worked correctly. So why did the Turbo Delphi 2006 compilation not work?

Community
  • 1
  • 1
Glenn1234
  • 2,542
  • 1
  • 16
  • 21

1 Answers1

5

In Delphi, unsigned types are just subrange types of the next larger signed type. In Delphi 3, there is no 64-bit type, so there is no next larger type for Cardinal to be a subrange of. Cardinal is a signed type in Delphi 3 because of a technical limitation in the language. Delphi 4 introduced Int64, and Cardinal was made to be an unsigned subrange of that type (and then the limitation was that the was no unsigned 64-bit type).

In short, you were never getting true unsigned behavior in the first place. Now that you've upgraded, you've exposed long-present problems that have always been in your code.

That your code compiled is no proof that your code was correct. Delphi 3 cannot enforce rules that require types it doesn't really have.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • I don't understand this at all. What is UInt64? And how can it explain the reported behaviour? – David Heffernan Dec 20 '12 at 13:52
  • @David, UInt64 is a type that didn't exist until much more recently. When Delphi versions were single digits (and possibly later), unsigned types were subranges of larger signed types: For UInt64 to exist, there would also need to be an Int128 type. I'm not sure whether that's still true in modern versions. – Rob Kennedy Dec 20 '12 at 13:58
  • There is no Int128. But UInt64 exists. But I still can't understand what you are driving at. Where can I learn more? – David Heffernan Dec 20 '12 at 14:02
  • @DavidHeffernan - Cardinal is 31-bit type in Delphi 2-3 – kludg Dec 20 '12 at 15:35
  • @David, this is stuff I learned in the newsgroups a decade ago, so check newsgroup archives, if they go back that far. I don't know where it's currently documented, or even whether it's still an accurate description of how unsigned types are represented in the compiler internals. It was definitely true for the versions I've talked about, though. Delphi 4 has no UInt64 type, although there are some internal library functions for unsigned 64-bit arithmetic (e.g., `lludiv`); they're just not exposed at the language level. – Rob Kennedy Dec 20 '12 at 15:35
  • see also http://books.google.ru/books?id=9JzBn4vcUBoC&pg=PA50&lpg=PA50&dq=delphi+3+cardinal&source=bl&ots=wySqJtsruS&sig=yvzz33vkKVKu0RYLlBWV8bWQ5Ww&hl=en&sa=X&ei=NC_TUMbGJu374QTUyoDIBg&redir_esc=y#v=onepage&q=delphi%203%20cardinal&f=false – kludg Dec 20 '12 at 15:37