- Feature Articles
- CodeSOD
-
Error'd
- Most Recent Articles
- Just Beastly
- All Michael
- Just a Taste
- Beer and Peanuts
- It's Our Party
- ABQ is the bomb
- Left Hand Right
- Testing 1,2,3,4,5
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
TRWTF is chaining strcat calls, which is Schlemiel the Painter's algorithm. (The underlying issue, of course, is that strcat is horribly designed.)
https://www.joelonsoftware.com/2001/12/11/back-to-basics/
Admin
But how does it know how long each of the 4096 records are?
Admin
Out of curiosity, are there even valid use cases for proprietary file systems? (Like, are there some embedded OSes that have hardware constraints so strict that they require something custom?)
Admin
But this code is so much more maintainable than having it all in a single string literal. What would happen if you need to change the number of records? With this code, you just have to change one simple value. If it were all in one string, you'd need to hunt through a huge string literal to find the value you need to change.
Admin
Aren't most file systems proprietary? NTFS has been mostly reverse engineered, but I think it's still proprietary.
Admin
"Proprietary" is probably the wrong word in context. I think that "domain-specific" might be better.
Admin
I wouldn't say that strcat is horribly designed. It's appropriately designed for C strings. C strings, on the other hand, are horribly designed... In a way, the design is elegant in its simplicity, but it's definitely not performance oriented.
Admin
C strings were designed when memory optimization was a priority. You only need to waste one byte for the null terminator, not multiple bytes for a length prefix, or even worse, a dope vector with a length and pointer.
Admin
to clarify: it's not 4096 records, but a file with fixed size records of 4096.
Admin
While I realize it's easy to avoid, the performance problems of Schlemiel the Painter are probably overblown unless you're dealing with very long strings and hundreds of concatenations. I usually use
sprintf()
, not just for performance but because it's clearer, but for short strings it's possible that the overhead of parsing the format string is worse than the back-and-forth of Schlemiel (unless the compiler is able to optimize it all away).Admin
Dan, to be more pedantic, the 512 is block size, not necessarily record size.
Admin
OK. Here's my alternate extended Pascal string implementation:
The first byte is the length of the string. If the length is less than 128, the next byte is the first byte of text. Thus, any string from 0 to 127 characters is the same length as its C equivalent.
If the top bit of the first byte is set, then the next byte is the high byte of the length and the text starts at byte 3. Note that this means that in strings of length 128 to 255, the second byte is zero.
You can repeat the semantics with the second byte and subsequent bytes if you want strings that are more than 65535 characters long.
Even for short strings, this incurs an extra comparison and a jump (to avoid loading the second byte) to get the length, compared to a Pascal string, but it's still faster than counting the characters.
Admin
Nope. This is a proprietary filesystem. One of the file types is fixed-N, where N is the size of records.
Admin
Record size of 4096. But what's the block size? Having flashbacks to JCL.....
Admin
The HW block size is irrelevant. This is what a user application is passing to fopen().
Admin
strcpy(str, "Now you see me"); strcat("\0Now you don't");
Admin
You missed something :)
Admin
Yeah, typed it on my phone - it's the worst way to code lol