4 ms·
I think this is something C++ (and other later ones) got right; A size field and a sentinel’d (null-terminated) char[]. So getting the length only requires read
by colejohnson66 6y ago
I think this is something C++ (and other later ones) got right; A size field and a sentinel’d (null-terminated) char[]. So getting the length only requires reading 4 or 8 bytes, but if you want to pass that string to a function that expects a null terminated string, just pass x.c_str().
- twic 6y agoIt would be even better if it was terminated by 8-len%8 null bytes, as that would make blocked loops simpler.
- deleted 6y ago[deleted]
- throwaway894345 6y agoThis seems useful if you're expecting to pass your strings to a lot of C libraries, which is probably sensible for C++ (especially whatever vintage of C++ happened to introduce this string design); however, surely this is a negligible concern for most mainstream languages?
- pengaru 6y ago> This seems useful if you're expecting to pass your strings to a lot of C libraries, which is probably sensible for C++ (especially whatever vintage of C++ happened to introduce this string design); however, surely this is a negligible concern for most mainstream languages? No, the system call interface of the operating system expects NUL-terminated strings as parameters all over the place, especially the filesystem APIs.
- steveklabnik 6y agoWho came first, the chicken or the egg? EDIT: Okay, this is at -1, maybe I shouldn't be slightly obtuse. These questions are, in my mind, two sides of the same coin. The OS expects null terminated strings, not for some inherent reason, but because C and UNIX grew up together. There's no inherent reason you can't have an OS that does not use sentinels to demarcate strings.
- throwaway894345 6y agoProbably my fault for phrasing the question ambiguously, but the parent interpreted my question as I intended it to be interpreted. Interfacing with the system libraries is a common enough case for using null-terminated strings. I'm actually a little curious how what these low-level APIs look like and how "modern" languages handle efficiently converting to null-terminated strings. Do they just copy everything while C/C++/etc would pass a straight reference? Also, what do the underlying syscall APIs look like?
- steveklabnik 6y agoIt's all good. You are 100% right that it's still a good use-case. And yeah, in Rust we have a separate CString type that's null terminated, so you may need a copy to move between the two worlds. It just depends, if you're only reading, for example, then you can create a pointer + len where the length doesn't include the 0, and that's effectively zero cost. You got me curious about my days as a kid putting "pascal" in front of Mac System 7 stuff; I believe that it only accepted Pascal strings. I also vaguely remember people doing funny stuff like null terminating pascal strings anyway and then putting the length before the actual pointer so that you get both in one...
- colejohnson66 6y agoWeren’t “Pascal strings” limited in that they were only a byte though? So, your string could only be 255 bytes long (conveniently going to a nice round 256 when you add the length byte).
- steveklabnik 6y agoYep!
- colejohnson66 6y agoFor most people, the time difference between reading 4/8 bytes and scanning for a null terminator is negligible, but there’s the other benefit of not having to worry as much about buffer overruns; If you append to a std::string and its internal buffer is full, it’ll realloc() its buffer. This does have the problem of the possibility of a realloc(), but I prefer that over buffer overruns.
- saagarjha 6y agoNote that C++11 got this right, this wasn't guaranteed prior to that.