Legal to overwrite std::string's null terminator?

后端 未结 4 417
感动是毒
感动是毒 2020-12-01 09:11

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 t

相关标签:
4条回答
  • 2020-12-01 09:36

    Unfortunately, this is UB, if I interpret the wording correct (in any case, it's not allowed):

    §21.4.5 [string.access] p2

    Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type T with value charT(); the referenced value shall not be modified.

    (Editorial error that it says T not charT.)

    .data() and .c_str() basically point back to operator[] (§21.4.7.1 [string.accessors] p1):

    Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].

    0 讨论(0)
  • 2020-12-01 09:44

    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?

    0 讨论(0)
  • 2020-12-01 09:48

    LWG 2475 made this valid by editing the specification of operator[](size()) (inserted text in bold):

    Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.

    0 讨论(0)
  • 2020-12-01 09:50

    According to the spec, overwriting the terminating NUL should be undefined behavior. So, the right thing to do would be to allocate length+1 characters in the string, pass the string buffer to the C API, and then resize() back to length:

    // "+ 1" to make room for the terminating NUL for the C API
    std::string str(length + 1);
    
    // Call the C API passing &str[0] to safely write to the string buffer
    ...
    
    // Resize back to length
    str.resize(length);
    

    (FWIW, I tried the "overwriting NUL" approach on MSVC10, and it works fine.)

    0 讨论(0)
提交回复
热议问题