Topic: basic_string functions and invalidation


Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/12/11
Raw View
Christopher Eltschka wrote:

>The parameter (i.e. string(p) ) must be evaluated before the
>call to operator=(string) is performed. After construction of
>the temporary string, this->operator= may not invalidate that
>other string. So I'd say there's no problem here.

That's how I was thinking of it, but in order for operator= to return
something, it has to be entered first, and the description concerns what it
returns. So, in a very technical sense, one could say that entry into (the
non-const) operator=(const char*) invalidates the pointer, before the
temporary can be created, but I certainly don't believe that's the intent. I
believe the intent is for operator= to have the same and only the effect of
what it is defined to return, in which case, mere entry into operator=
doesn't invalidate the pointer, and construction of the temporary within
operator= guards against future invalidation. (Note: A quality
implementation won't create all the temporaries the standard uses in its
definition of basic_string member functions, but it must act as if it does.)

--
Doug Harrison
dHarrison@worldnet.att.net


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/12/11
Raw View
AllanW@my-dejanews.com wrote:

>This makes a lot of sense, but I wasn't able to find it in the
>standard. Isn't it just as likely that the implementation of
>std::string::operator=(const char*) looks like this?
>    string &string::operator=(const char*arg) {
>        delete[] _data;
>        if (arg) {
>            strcpy(_data = new char[1+(_size=strlen(arg))], arg);
>        } else {
>            _data = 0;
>            _size = 0;
>        }
>        return *this;
>    }
>Of course we all see the problem here: if arg equals the initial
>value of _data, then
>    delete[] _data;
>also made the argument invalid (and the use in strlen and strcpy
>is therefore invalid).
>
>But does anything in the standard prohibit an implementor from
>providing this?

I certainly hope that isn't allowed. The standard defines operator=(const
char* p) as:

 Returns: *this = string(p)

I've always interpreted the "Returns" to mean "is equivalent to". Under this
interpretation, a quality implementation that wants to avoid creation of the
temporaries the standard uses to define operator=, append, replace, etc.
must still do the right thing, even if p points into the target string's
data, as if it was creating the temporaries.

Note that the members that take basic_string arguments place no restrictions
on the identity of these arguments, so they do support scenarios in which
the target and source strings are the same. I'm hoping that part of the
intent behind defining the char* overloads in terms of temporaries is to
extend this freedom to the char* overloads. But like you, I wish this was
spelled out.

--
Doug Harrison
dHarrison@worldnet.att.net


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/12/11
Raw View
In article <366FFAF1.7869@pratique.fr>,
  Valentin Bonnard <bonnardv@pratique.fr> wrote:
>
> Doug Harrison wrote:
> >
> > Is the following sort of thing supposed to be valid?
> >
> >  std::string s = "abc";
> >  s = s.c_str();
> >
> > The standard defines:
> >
> >  string::operator=(const char* p)
> >
> > as:
> >
> >  Returns: *this = string(p)
> >
> > The problem is that invocation of the non-const member, operator=, may be
> > thought to invalidate the c_str() result, before operator= has the chance
to
> > (conceptually) create a temporary from it, which otherwise avoids the
> > invalidation and overlapping data issues.
> >
> > I've always interpreted "Returns" as "has the same effect as", but
> > technically, that isn't really correct.
>
> It's a rewrite rule, so your code is ok.

Would you please cite the "rewrite rule"? I couldn't find this.

> From the implementor point of view, it's a bit like:
>
> s = s
>
> first do the copy, then destroy the current object
> or do the copy inplace

This makes a lot of sense, but I wasn't able to find it in the
standard. Isn't it just as likely that the implementation of
std::string::operator=(const char*) looks like this?
    string &string::operator=(const char*arg) {
        delete[] _data;
        if (arg) {
            strcpy(_data = new char[1+(_size=strlen(arg))], arg);
        } else {
            _data = 0;
            _size = 0;
        }
        return *this;
    }
Of course we all see the problem here: if arg equals the initial
value of _data, then
    delete[] _data;
also made the argument invalid (and the use in strlen and strcpy
is therefore invalid).

But does anything in the standard prohibit an implementor from
providing this?

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/12/10
Raw View
Is the following sort of thing supposed to be valid?

 std::string s = "abc";
 s = s.c_str();

The standard defines:

 string::operator=(const char* p)

as:

 Returns: *this = string(p)

The problem is that invocation of the non-const member, operator=, may be
thought to invalidate the c_str() result, before operator= has the chance to
(conceptually) create a temporary from it, which otherwise avoids the
invalidation and overlapping data issues.

I've always interpreted "Returns" as "has the same effect as", but
technically, that isn't really correct. However, I've seen no prohibition on
arguments that overlap the target string, and if a (simplistic)
implementation just copied from the standard, it would allow overlapping
data, so I think I have the intent right. Comments?

--
Doug Harrison
dHarrison@worldnet.att.net


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/10
Raw View
Doug Harrison wrote:
>
> Is the following sort of thing supposed to be valid?
>
>  std::string s = "abc";
>  s = s.c_str();
>
> The standard defines:
>
>  string::operator=(const char* p)
>
> as:
>
>  Returns: *this = string(p)
>
> The problem is that invocation of the non-const member, operator=, may be
> thought to invalidate the c_str() result, before operator= has the chance to
> (conceptually) create a temporary from it, which otherwise avoids the
> invalidation and overlapping data issues.

The parameter (i.e. string(p) ) must be evaluated before the
call to operator=(string) is performed. After construction of
the temporary string, this->operator= may not invalidate that
other string. So I'd say there's no problem here.

[...]


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/12/10
Raw View
Doug Harrison wrote:
>
> Is the following sort of thing supposed to be valid?
>
>  std::string s = "abc";
>  s = s.c_str();
>
> The standard defines:
>
>  string::operator=(const char* p)
>
> as:
>
>  Returns: *this = string(p)
>
> The problem is that invocation of the non-const member, operator=, may be
> thought to invalidate the c_str() result, before operator= has the chance to
> (conceptually) create a temporary from it, which otherwise avoids the
> invalidation and overlapping data issues.
>
> I've always interpreted "Returns" as "has the same effect as", but
> technically, that isn't really correct.

It's a rewrite rule, so your code is ok.