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.