Topic: MSVC++: bug in std::string::operator= ?


Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 16 Feb 2001 05:54:24 GMT
Raw View
Anthony Williams wrote:
...
> OK, I missed the original post. I thought someone was arguing about
>
> s=string(s.c_str());
>
> This has the set of sequence points I described.
>
> If it was
>
> s=s.c_str();

The original message pointed out that section 21.3.1 section 19 requires
that

 s = s.c_str();

is required to be equivalent to

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

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@spamcop.net>
Date: Fri, 16 Feb 2001 17:48:30 GMT
Raw View

"James Kuyper Jr." wrote:

> >
> > s=s.c_str();
>
> The original message pointed out that section 21.3.1 section 19 requires
> that
>
>         s = s.c_str();
>
> is required to be equivalent to
>
>         s = std::string(s.c_str());
>

It doesn't say that, which is the problem the original poster is missing.

It says that
 operator=(const charT* s)
RETURNS
 *this = std::string(s)

It doesn't preclude it from invalidating the return from a previous
this->c_str() call, which it is allowed to do since c_str() values
are invalid "after" a call to a non-const member.

The only point of discussion is what "after a call" means.  The original
poster interprets this to mean after the const-method returns.  This is
ludicrous to me.  It means the function call itself.  Once you're in the
boddy of the non-const member, all bets are off on previous c_str() return
values.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kanze <kanze@gabi-soft.de>
Date: Sat, 17 Feb 2001 18:46:30 GMT
Raw View
"P.J. Plauger" <pjp@dinkumware.com> writes:

|>  <kodaj@my-deja.com> wrote in message news:968pdv$vmq$1@nnrp1.deja.com...

|>  >   std::string s("Make sure it's longer than 31
|>  > characters");

|>  >   s = s.c_str();  // line 1
|>  >   std::cout << s << "\n";
|>  > .....
|>  > Under MSVC++ 6.0, the output is an empty string
|>  > (!) - the assignment destroys the contents of s.
|>  > Under GCC, the output is what you'd expect: "Make
|>  > sure..." etc.

|>  > So, is MSVC++ buggy, or is the behavior of this program undefined
|>  > according to the standard?

|>  Well, you obviously went gunning for VC++,

Seem to be an in thing to do:-).  Still, he was mild compared to most.
He probably should have mentionned his correspondance with Dinkumware,
but you could also interpret it that if though Dinkumware recognized it
as an error, he wasn't sure it was.

|>  by your choice of string
|>  length. You also posted this as a bug report at the Dinkumware web
|>  site and got a reply -- well before you made this newsgroup posting
|>  -- which you have failed to acknowledge. Here is what I said to you
|>  earlier:

|>    No. First, at the time that the library for V6.0 froze, string
|>    operations were not obliged to work properly with overlapping
|>    operands. Second, now that the C++ Standard has changed to
|>    (implicitly) require correct operation, we have altered our
|>    implementation to do so.

I'm still not convinced that the standard requires this to work,
although it is very much to Dinkumware's credit that they make it work.
Calling std::string::operator= invalidates the results from
std::string::c_str.  Which means that while you may have passed a valid
pointer to the function, the pointer isn't valid in the function.
Generally speaking, I think that there is a requirement (perhaps only
implicit) that all parameters passed to a function be valid for the
length of the function; no one would pretend an implemention non
conforming because it failed when the Function parameter to std::find
deleted the std::vector underlying the iterator parameters.  And my
interpretation is that simply calling operator= invalidates the pointer,
from the moment the function is entered.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Doug Farrell" <dfarrell01@earthlink.net>
Date: Sun, 18 Feb 2001 17:56:29 GMT
Raw View
Mr. Plauger,

I've been reading your comments for years in "C/C++ Users Journal" and
elsewhere, and again you have cleared up a fog in only a few lines. Thanks
for essentially ending this arguement, in my opinion.

Thanks,
Doug Farrell

"P.J. Plauger" <pjp@dinkumware.com> wrote in message
news:3a88a1c6$0$21436@wodc7nh0.news.uu.net...
> <kodaj@my-deja.com> wrote in message news:968pdv$vmq$1@nnrp1.deja.com...
>
> >   std::string s("Make sure it's longer than 31
> > characters");
> >
> >   s = s.c_str();  // line 1
> >   std::cout << s << "\n";
> > .....
> > Under MSVC++ 6.0, the output is an empty string
> > (!) - the assignment destroys the contents of s.
> > Under GCC, the output is what you'd expect: "Make
> > sure..." etc.
> >
> > So, is MSVC++ buggy, or is the behavior of this
> > program undefined according to the standard?
>
> Well, you obviously went gunning for VC++, by your choice
> of string length. You also posted this as a bug report at
> the Dinkumware web site and got a reply -- well before you
> made this newsgroup posting -- which you have failed to
> acknowledge. Here is what I said to you earlier:
>
>   No. First, at the time that the library for V6.0 froze, string
>   operations were not obliged to work properly with overlapping
>   operands. Second, now that the C++ Standard has changed to
>   (implicitly) require correct operation, we have altered our
>   implementation to do so.
>
> P.J. Plauger
> Dinkumware, Ltd.
> http://www.dinkumware.com
>
>
>
> ---
> [ 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://www.research.att.com/~austern/csc/faq.html                ]
> [ Note that the FAQ URL has changed!  Please update your bookmarks.     ]
>
>

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kodaj@my-deja.com
Date: Mon, 12 Feb 2001 19:13:01 GMT
Raw View
Hello to everyone,

Sorry if this is a newbie question, but I haven't
been able to find the answer anywhere in the
FAQ's.

My problem is the following: according to the
standard, what should this program print?

#include <string>
#include <iostream>

void main()
{
  std::string s("Make sure it's longer than 31
characters");

  s = s.c_str();  // line 1
  std::cout << s << "\n";
}

(Of course, you'd never do something like that -
the actual context in which we encountered the
problem was much more complicated, this is just
the essence.)

Under MSVC++ 6.0, the output is an empty string
(!) - the assignment destroys the contents of s.
Under GCC, the output is what you'd expect: "Make
sure..." etc.

So, is MSVC++ buggy, or is the behavior of this
program undefined according to the standard?
If I'm right, there are two crucial points to
consider here:
1. Is it OK to pass in the const char* pointer
returned by c_str() to operator= ?
2. What semantics does the standard require from
std::string::operator=( const char* )?

The Draft Standard says the following about these
issues:

- About 1:
**********
21.3.6 basic_string string operations
const charT* c_str() const;

2 [...] Nor shall the program treat the returned
value as a valid pointer value AFTER any
subsequent call to a non-const member function of
the class basic_string that designates the same
object as this.
*********

In my opinion, this means that the pointer
returned by c_str() is valid at the point of the
call to operator=, and thus it is OK to pass it
in.

- About 2:
**********
21.3.1 basic_string constructors

basic_string<charT,traits,Allocator>&
operator=(const charT* s);
19 Returns: *this =
basic_string<charT,traits,Allocator>( s).
*********

In my opinion, this means that line 1 should be
equivalent to this:
  s = std::string(s.c_str());

Obviously, MSVC++ does not meet this requirement.

To sum it up: to me it seems that the program is
legal according to the standard, and it should
behave as it does under GCC - which means that
the MSVC++ string implementation is buggy. Am I
right?

Thanks for the help in advance,

Bence Kodaj



Sent via Deja.com
http://www.deja.com/

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@spamcop.net>
Date: Mon, 12 Feb 2001 19:52:34 GMT
Raw View

kodaj@my-deja.com wrote:

> My problem is the following: according to the
> standard, what should this program print?

It ought not even to compile.  main must return int.

>
> So, is MSVC++ buggy, or is the behavior of this
> program undefined according to the standard?

My opinion is that it's undefined behavior.

> If I'm right, there are two crucial points to
> consider here:
> 1. Is it OK to pass in the const char* pointer
> returned by c_str() to operator= ?

Not on the same object.

> 2. What semantics does the standard require from
> std::string::operator=( const char* )?

As specified in the standard.

>
> The Draft Standard says the following about these
> issues:

You really ought to get the real standard.

>
> 2 [...] Nor shall the program treat the returned
> value as a valid pointer value AFTER any
> subsequent call to a non-const member function of
> the class basic_string that designates the same
> object as this.

Note that this says "after the call" not after the
called function returns.  Inside the called
function is after the call.  The values from c_str() is
invalid as soon as the operator starts to execute.

> In my opinion, this means that the pointer
> returned by c_str() is valid at the point of the
> call to operator=, and thus it is OK to pass it
> in.

It's OK to pass it, but as soon as it gets there, it's
invalid.

> In my opinion, this means that line 1 should be
> equivalent to this:
>   s = std::string(s.c_str());

But before it gets to initialize the temporary string
with c_str, the previous c_str() is invalidated.

> To sum it up: to me it seems that the program is
> legal according to the standard, and it should
> behave as it does under GCC - which means that
> the MSVC++ string implementation is buggy. Am I
> right?
>
My opinion is that as soon as operator=, a non-const
method, is called, the previous c_str() is invalid.
What the standard says what happens with the value
internal to the operator is immaterial since it's
already been invalidated by the call.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Tom <the_wid@my-deja.com>
Date: Mon, 12 Feb 2001 23:35:52 GMT
Raw View
Previously, kodaj@my-deja.com wrote in comp.std.c++:
[SNIP]
> - About 1:
> **********
> 21.3.6 basic_string string operations
> const charT* c_str() const;
>
> 2 [...] Nor shall the program treat the returned
> value as a valid pointer value AFTER any
> subsequent call to a non-const member function of
> the class basic_string that designates the same
> object as this.
> *********
>
> In my opinion, this means that the pointer
> returned by c_str() is valid at the point of the
> call to operator=, and thus it is OK to pass it
> in.

I don't agree with what you say here. The above has
nothing to say about what a string can do with its
own c_str() return inside its own code. "the
program" and the library are different. Clearly,
just before the end of the call to operator= (on
the return line) then the passed in c_str value is
invalid.

>
> - About 2:
> **********
> 21.3.1 basic_string constructors
>
> basic_string<charT,traits,Allocator>&
> operator=(const charT* s);
> 19 Returns: *this =
> basic_string<charT,traits,Allocator>( s).
> *********
>
> In my opinion, this means that line 1 should be
> equivalent to this:
>   s = std::string(s.c_str());
>
> Obviously, MSVC++ does not meet this requirement.

This I agree with. With the above effects, your code
must work and therefore MSVC is incorrect.

>
> To sum it up: to me it seems that the program is
> legal according to the standard, and it should
> behave as it does under GCC - which means that
> the MSVC++ string implementation is buggy. Am I
> right?

Yes, although I haven't checked the final standard
either. I assume that there aren't any pre-conditions
to operator=, such as s must not be part of the
controlled sequence of the string?

Tom

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Stefan Schwarzer <sts@tiger.ica1.uni-stuttgart.de>
Date: Tue, 13 Feb 2001 13:00:43 GMT
Raw View
Just my $0.02:
I agree with Ron.

>> *********
>>
>> In my opinion, this means that line 1 should be
>> equivalent to this:
>>   s = std::string(s.c_str());
>>

This is equivalent to

     operator=(s, std::string(s.c_str()));

I think that you have a sequence point issue here. Since IMHO
there are no sequence points in this expression, the compiler
has considerable freedom. Nothing guarantees that the
temporary string is constructed entirely before operator= is called.
If MSVC++ thinks the code is faster if it inlines operator=, starts
executing the code, maybe allocates a buffer for the assignment yet
to happen, only then constructs the temporary string (with what is left of
s.c_str() at that time), it is free to do so. Thus you invoke
undefined behavior.

>> To sum it up: to me it seems that the program is
>> legal according to the standard, and it should
>> behave as it does under GCC - which means that
>> the MSVC++ string implementation is buggy. Am I
>> right?

> Yes, although I haven't checked the final standard
> either. I assume that there aren't any pre-conditions
> to operator=, such as s must not be part of the
> controlled sequence of the string?

> Tom

I think MSVC++ is not to blame.

Stefan.


> ---
> [ 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://www.research.att.com/~austern/csc/faq.html                ]
> [ Note that the FAQ URL has changed!  Please update your bookmarks.     ]


--
Stefan Schwarzer                       office: +49-(0)711-685-7606 fax: x-3658
Uni Stuttgart, ICA 1         (?-
Pfaffenwaldring 27           //\                     sts@ica1.uni-stuttgart.de
70569 Stuttgart, Germany    -V_/----     http://www.ica1.uni-stuttgart.de/~sts

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "P.J. Plauger" <pjp@dinkumware.com>
Date: Tue, 13 Feb 2001 15:19:05 GMT
Raw View
<kodaj@my-deja.com> wrote in message news:968pdv$vmq$1@nnrp1.deja.com...

>   std::string s("Make sure it's longer than 31
> characters");
>
>   s = s.c_str();  // line 1
>   std::cout << s << "\n";
> .....
> Under MSVC++ 6.0, the output is an empty string
> (!) - the assignment destroys the contents of s.
> Under GCC, the output is what you'd expect: "Make
> sure..." etc.
>
> So, is MSVC++ buggy, or is the behavior of this
> program undefined according to the standard?

Well, you obviously went gunning for VC++, by your choice
of string length. You also posted this as a bug report at
the Dinkumware web site and got a reply -- well before you
made this newsgroup posting -- which you have failed to
acknowledge. Here is what I said to you earlier:

  No. First, at the time that the library for V6.0 froze, string
  operations were not obliged to work properly with overlapping
  operands. Second, now that the C++ Standard has changed to
  (implicitly) require correct operation, we have altered our
  implementation to do so.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Dennett <jdennett@acm.org>
Date: Tue, 13 Feb 2001 15:19:51 GMT
Raw View
Stefan Schwarzer wrote:
>
> Just my $0.02:
> I agree with Ron.
>
> >> *********
> >>
> >> In my opinion, this means that line 1 should be
> >> equivalent to this:
> >>   s = std::string(s.c_str());
> >>
>
> This is equivalent to
>
>      operator=(s, std::string(s.c_str()));
>
> I think that you have a sequence point issue here. Since IMHO
> there are no sequence points in this expression, the compiler
> has considerable freedom.

Sequence points exist after method calls, and after constructor
invocations.

There are sequence points implied by the .c_str() call, the
constructor of the std::string, and the call to operator =
(if the type is a non-builtin).

> Nothing guarantees that the
> temporary string is constructed entirely before operator= is called.

Before operator = is called, there is a sequence point by which
both of its arguments must have been evaluated.

> If MSVC++ thinks the code is faster if it inlines operator=, starts
> executing the code, maybe allocates a buffer for the assignment yet
> to happen, only then constructs the temporary string (with what is left of
> s.c_str() at that time), it is free to do so. Thus you invoke
> undefined behavior.

You invoke MSVC++, which is in error.

-- James Dennett

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@spamcop.net>
Date: Tue, 13 Feb 2001 16:12:14 GMT
Raw View

Stefan Schwarzer wrote:

> >> In my opinion, this means that line 1 should be
> >> equivalent to this:
> >>   s = std::string(s.c_str());
> >>
>
> This is equivalent to
>
>      operator=(s, std::string(s.c_str()));
>

Specifically, it "virutally" looks like this:

 std::string& operator=(const char* cp) {
    //  this->c_str now invalid.
    return *this = std::string(cp);
 }

The standard doesn't say that the return line is the ONLY thing
that can happen in operator=(charT*).  It says that is what the
return value is.  Pretend that the std::string specifically deallocated
the value c_str() points to on the entrance to each non-const function
(right where I have the comment line above).  This would be perfectly
conforming.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Tue, 13 Feb 2001 16:11:58 GMT
Raw View
"Stefan Schwarzer" <sts@tiger.ica1.uni-stuttgart.de> wrote in message
news:96b0bi$rm$1@infosun2.rus.uni-stuttgart.de...
>
> Just my $0.02:
> I agree with Ron.
>
> >> *********
> >>
> >> In my opinion, this means that line 1 should be
> >> equivalent to this:
> >>   s = std::string(s.c_str());
> >>
>
> This is equivalent to
>
>      operator=(s, std::string(s.c_str()));
>
> I think that you have a sequence point issue here. Since IMHO
> there are no sequence points in this expression, the compiler
> has considerable freedom. Nothing guarantees that the
> temporary string is constructed entirely before operator= is called.
> If MSVC++ thinks the code is faster if it inlines operator=, starts
> executing the code, maybe allocates a buffer for the assignment yet
> to happen, only then constructs the temporary string (with what is left of
> s.c_str() at that time), it is free to do so. Thus you invoke
> undefined behavior.

There are at least 4 sequence points here - there is one at the beginning
and end of each function call. s.c_str() is a function call. The call to the
constructor std::string(const char*) is a function call, and finally the
call to std::string::operator=(const std::string&) is a function call.

Thus we have the following execution:

<SEQUENCE_POINT>
s.c_str() should be evaluated, yielding a pointer into storage owned by s.
<SEQUENCE_POINT>
a temporary string is constructed by calling std::string(const char*) with
the result of the call to s.c_str();
<SEQUENCE_POINT>
std::string::operator=(const std::string&) is called on s, with the
temporary string as the argument
<SEQUENCE_POINT>

>
> >> To sum it up: to me it seems that the program is
> >> legal according to the standard, and it should
> >> behave as it does under GCC - which means that
> >> the MSVC++ string implementation is buggy. Am I
> >> right?
>
> > Yes, although I haven't checked the final standard
> > either. I assume that there aren't any pre-conditions
> > to operator=, such as s must not be part of the
> > controlled sequence of the string?

There aren't any such preconditions, and I agree that MSVC is buggy.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks
The opinions expressed in this message are mine and do not represent those
of my employer



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Ron Natalie <ron@spamcop.net>
Date: Tue, 13 Feb 2001 17:51:50 GMT
Raw View

Anthony Williams wrote:
>

> There are at least 4 sequence points here - there is one at the beginning
> and end of each function call. s.c_str() is a function call. The call to the
> constructor std::string(const char*) is a function call, and finally the
> call to std::string::operator=(const std::string&) is a function call.

Sequence points aren't the issue.

> <SEQUENCE_POINT>
> s.c_str() should be evaluated, yielding a pointer into storage owned by s.
> <SEQUENCE_POINT>

You've missed a step.  The call to operator=(const char*) has it's own sequence
point here.  You've left out an entire function call.  Notably, one to a non-const
member, which is specifically the condition that invalidates the value returned
from c_Str().

<SEQEUNCE_POINT>

> a temporary string is constructed by calling std::string(const char*) with
> the result of the call to s.c_str();
> <SEQUENCE_POINT>
> std::string::operator=(const std::string&) is called on s, with the
> temporary string as the argument
> <SEQUENCE_POINT>

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: Tue, 13 Feb 2001 20:38:47 GMT
Raw View
"P.J. Plauger" <pjp@dinkumware.com> wrote in message
news:3a88a1c6$0$21436@wodc7nh0.news.uu.net...
>   No. First, at the time that the library for V6.0 froze, string
>   operations were not obliged to work properly with overlapping
>   operands. Second, now that the C++ Standard has changed to
>   (implicitly) require correct operation, we have altered our
>   implementation to do so.

Cool. So a portable implementation of operator= (ignoring template arguments
etc.) is:

class string
{
    ...
    string& operator=(const value_type* s)
    {
        string(s).swap(*this);
        return *this;
    }
};

Then, if we want to optimize memory allocation and stay 100% portable, we'd
like to verify whether s is in the memory area of our string. But we can't
use < for comparing pointers because it's undefined for pointers not
pointing inside the same memory chunk. Fortunately, there is a way out of
it - std::less is able to compare *any* pointers. So:

class string
{
    ...
    string& operator=(const value_type* s)
    {
        std::less<value_type*> comp;
        if (comp(&*begin(), s) && !comp(end(), s))
        {
            string(s).swap(*this);
        }
        else
        {
            replace(0, size(), s);
        }
        return *this;
    }
};

Is my reasoning correct?


Andrei


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Thu, 15 Feb 2001 19:09:07 GMT
Raw View
"Ron Natalie" <ron@spamcop.net> wrote in message
news:3A896A5F.2547CE06@spamcop.net...
>
>
> Anthony Williams wrote:
> >
>
> > <SEQUENCE_POINT>
> > s.c_str() should be evaluated, yielding a pointer into storage owned by
s.
> > <SEQUENCE_POINT>
>
> You've missed a step.  The call to operator=(const char*) has it's own
sequence
> point here.  You've left out an entire function call.  Notably, one to a
non-const
> member, which is specifically the condition that invalidates the value
returned
> from c_Str().
>
> <SEQEUNCE_POINT>
>

OK, I missed the original post. I thought someone was arguing about

s=string(s.c_str());

This has the set of sequence points I described.

If it was

s=s.c_str();

in the original post, then I retract my message - operator=(const char*) is
called on the result of s.c_str(), which I don't think is required to work,
for the reason you mention.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks
The opinions expressed in this message are mine and do not represent those
of my employer



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]