On Wed, 19 Apr 2017 01:40:39 -0700 (PDT)
Frits van Bommel <
fvbo...@gmail.com> wrote:
> On Wednesday, April 19, 2017 at 9:10:16 AM UTC+2, hui zhang wrote:
> >
> > for 1) you mean
> >>
> >> char *CGetPath() {
> >> return getpath().c_str();
> >> }
> >
> >
> > this code will work ?
> >
>
> That depends on whether getpath() returns a std::string or a (const)
> std::string& (a (const) reference). It will work if it returns a
> reference or const reference, but is not guaranteed to work if it
> doesn't (though it may appear to do so in some cases, or for some
> implementations of the C++ standard lib) because the standard lib is
> not required to use a reference-counted dynamic array. For example,
> it might instead choose to copy the array every time or to allocate
> small strings using an in-object buffer to avoid the overhead of
> dynamic allocation, and in both of those cases the return value of
> c_str() is no longer valid when the function returns.
I think that [1] guarantees that it's perfectly OK to return the value
returned by c_str() from a function unless the object we've called
c_str() on gets destructed upon that return (i.e. it was an automatic
or "RAII-d" variable in that function). That is, if the OP can
guarantee that the std::string object being discussed was live at the
time getpath() was called and is live after that call was finished,
it's fine to use whatever c_str() returned.
To cite [1] once again:
| The pointer obtained from c_str() may be invalidated by:
| * Passing a non-const reference to the string to any standard library
| function, or
| * Calling non-const member functions on the string, excluding
| operator[], at(), front(), back(), begin(), rbegin(), end() and
| rend().
> Even better might be to call GoString(getpath().c_str()) in
> the CGetPath function to ensure only a single copy is made, but I'm
> not familiar enough with cgo to know if that's possible.
Unfortunately, that's not possible: cgo can be thought of as providing
some sort of API for both sides -- the C's and the Go's and allowing
them both to interact via those APIs. It's impossible to arbitrarily
mix and match C and Go sides in expressions, so you'll have to arm your
C side with a function which would do getpath().c_str() and call it to
produce an input value for GoString(). But this actually changes
nothing in the semantics in this particular case -- see above.
1.
http://en.cppreference.com/w/cpp/string/basic_string/c_str