c_str() 的要求是否使修改非法?

Do c_str()'s requirements make modification illegal?

我的 C++ 标准草案副本(标记为“ISO/IEC JTC1 SC22 WG21 N3690 日期:2013-05-15") 对 basic_string::c_str()basic_string::data().

的定义如下
const charT* c_str() const noexcept; 
const charT* data() const noexcept;

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

Complexity: constant time.

Requires: The program shall not alter any of the values stored in the character array.

那么,下面的 C++ 程序似乎有未定义的行为,因为它跳过了 c_str() 的要求:

#include <string>
int main() {
  std::string foo = "foo";
  foo.c_str();
  foo[2] = 'p';
}

这看起来非常愚蠢。我是否误解了标准,或者 c_str 的这个要求是过去时代的遗物?

你的解释是错误的。 char * returned指向的数组不应该被修改。

这是不允许的

#include <string>
int main() 
{
    std::string foo = "foo";
    char * ptr = (char *)foo.c_str();
    ptr[2] = 'p'; // undefined
}

可以修改原始字符串,但这会使 c_str

的 return 无效

特定的措辞是 C++03 时代规范的遗留物,该规范允许写时复制字符串。 some point in the past c_str() 的规范为:

Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements equal the corresponding elements of the string controlled by *this and whose last element is a null character specified by charT().

Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of the class basic_string that designates the same object as this.

在这种情况下,要求更有意义。如果 c_str() 返回指向不同 std::string 之间共享的字符串的指针,则修改数组中的值将非常糟糕。

在 C++14 中,此禁令意义不大。正如您所指出的,将其解读为在 c_str() 调用之后完全禁止修改字符串没有多大意义;将其解读为禁止通过返回的指针修改 string 会稍微更有意义,但意义不大。 c_str() 返回的指针和使用 &operator[](0).

返回的指针之间的语义应该不同没有真正的原因