It's actually not at all certain. But everything points to storage block sizes.
The hints don't really start in the DBF file structure but in index file structures. When you look into them, you find structures with 512 bytes or 1024 bytes length:
For example, the IDX header has 512 bytes up to "key expression pool length" and then 512 more bytes for "key expression pool (uncompiled)". And in the same topic node records have 512 bytes length.
When you define a dbf just having a c(254) field, the RecSize is 255. Still room for 1 more byte, or actually 257 more bytes, with 512-byte blocks in mind.
The RecSize of different record structures is puzzling, if you don't know the details, here are some hints:
Code:
Create Cursor crsTest (ctest c(254))
? Recsize()
Create Cursor crsTest (ctest c(254) null)
? Recsize()
Create Cursor crsTest (ctest c(254) null, ctest2 c(254))
? Recsize()
Create Cursor crsTest (ctest c(254) null, ctest2 c(254) null)
? Recsize()
If you ask me, the limit wasn't set to the best value for achieving record sizes that can align with storage device block sizes. When you'd think of the simplest record only having a single char field and have the 512-byte blocks the limit should be 510. And indeed you could make the limit much more open and leave it to the developer to optimize record structures for storage block size alignment since that will strongly depend on the record structure, which will usually have at least one more id field.
And even in the 80s the usual memory wasn't drum-memory. It's hard to reconstruct what was considered in the definition, also because much of it was inherited from dBase file structures.
And when you look in detail, the file structure definition is wasteful with the full byte for the deleted flag. Especially when you know that the record only grows by 1 more byte for every 8 nullable fields, so a nullable field only gets 1 bit of a null flags byte, they could have used the deleted flag byte to store the first 7 null flag bits besides one bit for the deleted state. So, question after question:
Why so economical with null flag bits but not the deleted flag?
Why not orient to 512-byte blocks and allow max length of 510 bytes per char field?
Why not orient to a record structure that also has a 4-byte integer id/key field and lower the limit to 506?
Or why not leave it to the developer to align RecSize to device block sizes and define limits, which look more intuitive to developers, like 1024 or even 64kb limit?
Anyway, it is, what it is.
So I think the only final answer is because that's what's documented in system capacities. Sorry for wasting your time.
In the end, there is a point in that nobody needs more than 67 characters in a string. "Pippilotta Viktualia Rullgardina Krusmynta Efraimsdotter Långstrump" only has 67 characters. See?
I close my case.
Bye, Olaf.
Olaf Doschke Software Engineering