Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using &front() to modify underlying character array in std::string [duplicate]

Tags:

c++

c++11

I have to interface with a C library in one of my programs, and I am writing a thin wrapper to use C++ types such as std::string. There are quite a number of functions that accept a char* and a maximum length as parameter and overwrite the memory pointed to by the char* with a zero-terminated C-string. Traditionally, I used a stack array and copied the data into a string manually.

std::string call_C_function(int x) {
    char buf[MAX_LEN] = {0}; // MAX_LEN is defined by the library
    size_t len = MAX_LEN;
    C_function(x, buf, &len);
    return std::string(buf, len);
}

I tried to avoid the copy and came up with a solution, but I don't know if this is strictly legal:

std::string call_C_function(int x) {
    std::string buf(MAX_LEN, '\0'); // MAX_LEN is defined by the library
    size_t len = MAX_LEN;
    C_function(x, &buf.front(), &len);
    buf.resize(len);
    return buf;
}

This compiles and works, but I am having doubts because the std::string class makes it quite hard to get a non-const pointer to the character data. c_str() and data() both return const pointers. The standard forbids modifications of the buffer explicitly for these functions:

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

From the documentation, it seems that this is legal because front() returns a reference to the first character of the buffer which must be continuous (I am using C++11/14). In 21.4.5, the semantics of front() is defined in terms of operator[](0) which does not forbid modifications.

Are there any issues with this approach from a language standard point of view? It seems that this would be a loop-hole allowing the modification explicitly forbidden in 21.4.7.1.

like image 595
Jens Avatar asked Jul 21 '26 01:07

Jens


1 Answers

This is fine. You aren't allowed to modify the string via a pointer returned from a const member function but that doesn't mean you aren't allowed to modify the string at all. You have a non-const string, so you can modify it. In principle it's no different to doing s[0] = 'a'; s[1] = 'b'; etc.

It is forbidden to overwrite the final '\0' that is stored after the string data, but I assume from your example that MAX_LEN includes the space for the null terminator that is written by the C function, so the C function will only overwrite the string contents and not the extra character stored afterwards.

There is an open issue (LWG 2391) proposing to add a non-const std::string::data() which would be equivalent to &s.front(), and would give you direct access without making you concerned about going against the intention of the library.

like image 58
Jonathan Wakely Avatar answered Jul 23 '26 10:07

Jonathan Wakely



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!