I have an object of the
// C function
void foo(char* buf);
// C++ code
In practice, yes. There are exactly zero implementations of
std::string that are standards-comforming that do not store a NUL character at the end of the buffer.
So if you aren't wondering for wondering sake, you are done.
However, if you are wondering about the standard being abtruse:
In C++14, yes. There is a clear requirement that
 return a contiguous set of elements, and
[size()] must return a NUL character, and const methods may not modify state. So
*((&str)+size()) must be the same as
str[size()] must be a NUL, thus game over.
In C++11, almost certainly. There are rules that
const methods may not modify state. There are guarantees that
c_str() return a null-terminated buffer that agrees with
 at each point.
A convoluted reading of C++11 standard would state that prior to any call of
[size()] doesn't return the NUL terminator at the end of the buffer but rather a
static const CharT that is stored separately, and the buffer has an unitialized (or even a trap value) where NUL should be. Due to the requirement that
const methods not modify state I believe this reading is incorrect.
&str[str.size()] change between calls to
.data(), which is an observable change in state in
string over a
const call, which I would read as being illegal.
An alternative way to get around the standard might be to not initialize
str[str.size()] until you legally access it via calling
.c_str() or actually passing
operator. As there are no defined ways to access that element other than those 3 in the standard, you could stretch things and say lazy initialization of the NUL is legal.
I'd question this, as the definition of
.data() implies that the return value of
 is contiguous, so
& is the same address as
.data()+.size() is guaranteed to point to a NUL
CharT so must
(&)+.size(), and with no non-
const methods called the state of the
std::string may not change between the calls.
But, what if the fact the compiler can look and see you'll never call
.c_str(), does the requirement of contiguity hold if it can be proven you never call them?
At which point I'd throw my hands up and shoot the hostile compiler.
The standard is very passively voiced about this. So there may be a way to make an arguably standards conforming
std::string that doesn't follow these rules. And because the guarantees get closer and closer to explicitly requiring that NUL terminator there, the odds against a new compiler showing up that uses a tortured reading of C++ to claim this is standards compliant is low.