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)
.
返回的指针之间的语义应该不同没有真正的原因
我的 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 thatp + i == &operator[](i)
for eachi
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
特定的措辞是 C++03 时代规范的遗留物,该规范允许写时复制字符串。 some point in the past c_str()
的规范为:
Returns: A pointer to the initial element of an array of length
size() + 1
whose firstsize()
elements equal the corresponding elements of the string controlled by*this
and whose last element is a null character specified bycharT()
.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 classbasic_string
that designates the same object asthis
.
在这种情况下,要求更有意义。如果 c_str()
返回指向不同 std::string
之间共享的字符串的指针,则修改数组中的值将非常糟糕。
在 C++14 中,此禁令意义不大。正如您所指出的,将其解读为在 c_str()
调用之后完全禁止修改字符串没有多大意义;将其解读为禁止通过返回的指针修改 string
会稍微更有意义,但意义不大。 c_str()
返回的指针和使用 &operator[](0)
.