In C++11, we know that std::string
is guaranteed to be both contiguous and null-terminated (or more pedantically, terminated by charT()
, which in the case of char
is the null character 0).
There is this C API I need to use that fills in a string by pointer. It writes the whole string + null terminator. In C++03, I was always forced to use a vector<char>
, because I couldn't assume that string
was contiguous or null-terminated. But in C++11 (assuming a properly conforming basic_string
class, which is still iffy in some standard libraries), I can.
Or can I? When I do this:
std::string str(length);
The string will allocate length+1
bytes, with the last filled in by the null-terminator. That's good. But when I pass this off to the C API, it's going to write length+1
characters. It's going to overwrite the null-terminator.
Admittedly, it's going to overwrite the null-terminator with a null character. Odds are good that this will work (indeed, I can't imagine how it couldn't work).
But I don't care about what "works". I want to know, according to the spec, whether it's OK to overwrite the null-terminator with a null character?
According to the spec, overwriting the terminating
NUL
should be undefined behavior. So, the right thing to do would be to allocatelength+1
characters in the string, pass the string buffer to the C API, and thenresize()
back tolength
:(FWIW, I tried the "overwriting NUL" approach on MSVC10, and it works fine.)
I suppose n3092 isn't current any more but that's what I have. Section 21.4.5 allows access to a single element. It requires pos <= size(). If pos < size() then you get the actual element, otherwise (i.e. if pos == size()) then you get a non-modifiable reference.
I think that as far as the programming language is concerned, a kind of access which could modify the value is considered a modification even if the new value is the same as the old value.
Does g++ have a pedantic library that you can link to?
LWG 2475 made this valid by editing the specification of
operator[](size())
(inserted text in bold):Unfortunately, this is UB, if I interpret the wording correct (in any case, it's not allowed):
§21.4.5 [string.access] p2
(Editorial error that it says
T
notcharT
.).data()
and.c_str()
basically point back tooperator[]
(§21.4.7.1 [string.accessors] p1
):