- Feature Articles
- CodeSOD
- Error'd
- 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
There were some APIs (not necessarily sure how the underlying filesystem was implemented) on old IBM or VAX mainframes (my C language class used an ancient VMS system) where you had to specify if a file consisted of fixed size records vs byte stream, random access vs sequential, etc. I guess filesystems would enforce that in some way back then.
I kind of think the same 'statement of intent' API could be useful today as it would provide hints to the OS about read-ahead, caching policy, etc.
Admin
I taught C programming during the 80s and early 90s. I was stunned to see how many C programmers thought you had to supply the NUL yourself. And I'm not talking about my students. That blunder was quickly pointed out when I returned assignments. No, this was so often in "professional" code. sigh Forty+ years of this and still trying to keep my chin up.
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
Joel had made many critiques of the form "a clueless programmer could misuse it." That is not entirely meritless, but neither is it unequivocally a problem with the technology.
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
"Having flashbacks to JCL....." JTSD should be in the DSM.
Admin
Hmm. I think there are actually 2 numbers you need to record for a string variable - how long the string is, and the maximum length it can be.
Admin
And then your code breaks when somebody uses UTF-8 strings . Or in many european lanuages chars like åäöÅÄÖ :-)
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
Admin
No, it's not.