top | item 22198662

(no title)

braindeath | 6 years ago

How do you "plugin" the NUL. If there's no space for it, then everytime you want a C string, you need to do an allocation. And why would you put something in it's place - as you said if you modify the c_str that was always UB -- so you pretty much lost all guarantees at that point -- that was just dumb.

Basically the NUL-terminator amounts to a 1-byte of wasted space -- which is almost always completely in the noise -- if you're using std::string for tiny strings you're paying at least 24 bytes anyway. There are just very few cases where that one extra byte matters.

I think the overwhelming opinion is that this 1-byte trade-off is better than the overhead of allocation and copying when you want to pass that string around. NUL-terminated strings aren't important in C++ because of C (well, not directly), but because they are essentially the ABI of countless existing libraries and the major operating systems.

> code that depends on NUL termination is not a thing to be proud of.

Whatever. Code that depends on NUL termination is ubiquitous.

discuss

order

ncmncm|6 years ago

>How do you "plugin" the NUL. If there's no space for it, then everytime you want a C string, you need to do an allocation.

You have not thought it through. There was always space for a NUL, but nobody needs it to have a NUL in it until somebody calls c_str(). Anyway, that was true until somebody jiggered the Standard, just before 1998, to require a NUL visible to s[s.size()].

>C Code that depends on NUL termination is ubiquitous.

Fixed that for you.

braindeath|6 years ago

> Anyway, that was true until somebody jiggered the Standard, just before 1998, to require a NUL visible to s[s.size()].

This is not technically true. You could plugin your hated NUL byte in the implementation of operator [].

> C Code that depends on NUL termination is ubiquitous.

No, that's not what I said. It really doesn't matter what language underlying the API of all the code that expects NUL terminated strings is written in (a lot of it is C++ of course too). Windows, MacOS, and all POSIX-ish systems have a large API that consumes NUL terminated strings. NUL terminated strings are ubiquitous in computing at this point. Sure blame C from 40 years ago and burn a dmr effigy, I don't care, but that battle was long lost.

NUL terminated strings may be terrible, but the C++ accomodation for them is not -- its a well-thought out trade-off. My understanding is that neither go nor Rust make this trade-off. golangs FFI and syscall overhead has always been something of a performance disaster anyway. C++ has always had a greater demand to "play nice" with legacy code and systems then either of those.

The overhead of just having the NUL-byte is almost always a non-factor. If it really is, then use a byte vector.

BubRoss|6 years ago

Are you saying that there should not be an extra 0 byte at the end until the string fills up and c_str() is called? Inconsistent allocations seem like a recipe for difficult to debug performance problems.