C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Defect Report: basic_string's const method c_str() can inval

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Ryan Myers
Guest





PostPosted: Sat Oct 04, 2003 4:28 pm    Post subject: Defect Report: basic_string's const method c_str() can inval Reply with quote




This DR concerns a contradiction in ISO/IEC IS 14882:1998(E) between section
21.3 [lib.basic.string] paragraph 5, and section 21.3.6 [lib.string.ops]
paragraph 1.

In 21.3 paragraph 5 (p384), the Standard states:

"References, pointers, and iterators referring to the elements of a
basic_string sequence may be invalidated by the following uses of that
basic_string object:
...
— Calling data() and c_str() member functions."

However, in 21.3.6 paragraph 1 (p397), both c_str() and data() are defined
as being const. By the definition of const, both methods should be
incapable of invalidating iterators.

As most libc implementations simply have said methods return a pointer to
the string's backing store, this is not an active problem; however, it is an
inconsistency. It is capable of producing difficult-to-track bugs in
functions that pass strings by const reference; the callee is capable of
invalidating iterators/references used in the caller, breaking
encapsulation.

The most reasonable fix appears to be modifying 21.3 to remove the ability
of data() and c_str() to invalidate. This does not break existing code; it
is an increase in the promises offered by the standard, while still allowing
for string implementations that use shared backing pools for performance.

Thanks,

~ Ryan Myers <root (AT) poweredbyg (DOT) nu>



[ 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.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Bob Bell
Guest





PostPosted: Sun Oct 05, 2003 6:11 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote



"Ryan Myers" <root (AT) poweredbyg (DOT) nu> wrote

Quote:
This DR concerns a contradiction in ISO/IEC IS 14882:1998(E) between section
21.3 [lib.basic.string] paragraph 5, and section 21.3.6 [lib.string.ops]
paragraph 1.

In 21.3 paragraph 5 (p384), the Standard states:

"References, pointers, and iterators referring to the elements of a
basic_string sequence may be invalidated by the following uses of that
basic_string object:
...
? Calling data() and c_str() member functions."

However, in 21.3.6 paragraph 1 (p397), both c_str() and data() are defined
as being const. By the definition of const, both methods should be
incapable of invalidating iterators.

I don't see why const members should not invalidate iterators. Since
this assertion is the foundation of the report, I don't think there's
a defect here.

Bob

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Anaravescio
Guest





PostPosted: Sun Oct 05, 2003 6:54 pm    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote



"Bob Bell" <belvis (AT) pacbell (DOT) net> wrote:

Quote:
I don't see why const members should not invalidate iterators. Since
this assertion is the foundation of the report, I don't think there's
a defect here.

The only way said methods can invalidate references, pointers, or iterators
is if you're modifying the internal state of the string, moving the backing
store; by definition, this is something a const member function should be
incapable of doing, since its this ptr is const. (Can anyone think of a
situation where you could invalidate references WITHOUT modifying the
string's state?) But to illustrate why this makes bugs hard to track,
here's a small degenerate example:

void wraps_some_c_function(char c, const string & str)
{
...
frob(c, str.c_str());
...
}

void parse(string input)
{
for (string::iterator i = input.begin(); i != input.end(); ++i)
{
wraps_some_c_function(*i, input);
}
}

Since the argument to wraps_some_c_function() is const, we're allowed to
call c_str(), and it'll work as expected; however, the behavior of parse()
after it returns will be undefined. This bug can be hard to track down,
especially if the c_str() call is buried eight or nine function levels deep.
It's just as problematic if any callers up the chain have any references
from, say, a call to input[i] lying around.

~ Ryan Myers [email]root (AT) poweredbyg (DOT) nu[/email]


---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
James Kuyper
Guest





PostPosted: Tue Oct 07, 2003 12:46 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote

[email]fap (AT) fap (DOT) com[/email] ("Anaravescio") wrote in message news:<3f7fc900$1 (AT) nntp0 (DOT) pdx.net>...
Quote:
"Bob Bell" <belvis (AT) pacbell (DOT) net> wrote:

I don't see why const members should not invalidate iterators. Since
this assertion is the foundation of the report, I don't think there's
a defect here.

The only way said methods can invalidate references, pointers, or iterators
is if you're modifying the internal state of the string, moving the backing
store; by definition, this is something a const member function should be
incapable of doing, since its this ptr is const.

That's not true if the object contains a mutable member, or a pointer
to a non-const object.

Quote:
... (Can anyone think of a
situation where you could invalidate references WITHOUT modifying the
string's state?)

Yes, by changing the state of an object pointed at by a pointer which
is part of the string's state.

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Oct 07, 2003 12:46 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote

"Ryan Myers" <root (AT) poweredbyg (DOT) nu> wrote

Quote:
This DR concerns a contradiction in ISO/IEC IS 14882:1998(E) between
section 21.3 [lib.basic.string] paragraph 5, and section 21.3.6
[lib.string.ops] paragraph 1.

In 21.3 paragraph 5 (p384), the Standard states:

"References, pointers, and iterators referring to the elements of a
basic_string sequence may be invalidated by the following uses of that
basic_string object:
...
? Calling data() and c_str() member functions."

However, in 21.3.6 paragraph 1 (p397), both c_str() and data() are
defined as being const. By the definition of const, both methods
should be incapable of invalidating iterators.

I fail to see any relationship. If the standard says that they may
invalidate iterators, they may invalidate iterators. If the standard
says they may not, they may not. Const has nothing to do with it.

Quote:
As most libc implementations simply have said methods return a pointer
to the string's backing store,

But this is not required. In fact, there is no requirement that the
backing store be contiguous. However, the pointer returned by data or
c_str must point to a contiguous buffer. There are several ways to
achieve this using a non contiguous backing store; one is to simply
switch to contiguous backing store when either of these functions are
called. If the iterators also point into the backing store, this will
invalidate them.

Quote:
this is not an active problem; however, it is an inconsistency. It is
capable of producing difficult-to-track bugs in functions that pass
strings by const reference; the callee is capable of invalidating
iterators/references used in the caller, breaking encapsulation.

In general, iterators which can be invalidated can cause difficult to
track bugs. That's part of the philosophy of the STL.

Quote:
The most reasonable fix appears to be modifying 21.3 to remove the
ability of data() and c_str() to invalidate. This does not break
existing code; it is an increase in the promises offered by the
standard, while still allowing for string implementations that use
shared backing pools for performance.

To be frank, I'm not too sure what we should do with std::string. The
current interface doesn't allow efficient implementations anyway, so
maybe we should just go the full route, more or less impose a specific
implementation, and accept the fact that anyone needing an efficient
string will have to write their own.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
johnchx
Guest





PostPosted: Tue Oct 07, 2003 12:46 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote

[email]fap (AT) fap (DOT) com[/email] ("Anaravescio") wrote i
Quote:

I don't see why const members should not invalidate iterators. Since
this assertion is the foundation of the report, I don't think there's
a defect here.

The only way said methods can invalidate references, pointers, or iterators
is if you're modifying the internal state of the string, moving the backing
store; by definition, this is something a const member function should be
incapable of doing, since its this ptr is const.

std::strings are allowed to have mutable members.

I suspect that the reason for allowing a string to invalidate
iterators in this situation is to permit an implementation with a
non-contiguous backing store which "re-arranges" itself into a
contiguous buffer when data() or c_str() is called.

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Alexander Terekhov
Guest





PostPosted: Tue Oct 07, 2003 5:47 pm    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote


[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
[...]
Quote:
In fact, there is no requirement that the
backing store be contiguous. However, the pointer returned by data or
c_str must point to a contiguous buffer. There are several ways to
achieve this using a non contiguous backing store; one is to simply
switch to contiguous backing store when either of these functions are
called. If the iterators also point into the backing store, this will
invalidate them.

This will also make it impossible to call c_str()/data() CONCURRENTLY
with respect to {almost} any other CONST operation on the same object.

Confusing, to say the least.

regards,
alexander.

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Ryan Myers
Guest





PostPosted: Wed Oct 08, 2003 7:20 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote

Minor correction: I'm informed by my colleague that it was in fact the
Principle of Least Astonishment I was thinking of, although hopefully the
idea was transmitted well enough.

The issue at hand really isn't whether or not it should or should not const;
it's that its sideeffects as stated run contrary to what its intended use
is. c_str() exists to provide an alternate _view_ of the data inside the
string; that view can be immutable if need be, as long as it's accurate.
Technically, I could write my own getCStr() which just returned a
boost::shared_array<T *> and iterated through the entire string copying a
char at a time, but I think it's reasonable to suggest that doing so really
shouldn't be necessary.

Unfortunately, after absorbing the views of everyone here, I can't see a way
to correct c_str() without either breaking old code or placing obviously
unwelcome restrictions upon implementors, so I suggest that this DR should
be withdrawn. However, I still see the need for what may end up being an
alternate string class that strikes a more appropriate balance between
implementor freedom and usability. (It would also be a chance to go back
and reverse some of the other annoyances of basic_string, such as npos.)

~ Ryan Myers <root (AT) poweredbyg (DOT) nu>


---
[ 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.jamesd.demon.co.uk/csc/faq.html ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Oct 10, 2003 1:17 am    Post subject: Re: Defect Report: basic_string's const method c_str() can i Reply with quote

[email]terekhov (AT) web (DOT) de[/email] (Alexander Terekhov) wrote in message
news:<3F82893E.D05AB97D (AT) web (DOT) de>...
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:
[...]
In fact, there is no requirement that the
backing store be contiguous. However, the pointer returned by data or
c_str must point to a contiguous buffer. There are several ways to
achieve this using a non contiguous backing store; one is to simply
switch to contiguous backing store when either of these functions are
called. If the iterators also point into the backing store, this will
invalidate them.

This will also make it impossible to call c_str()/data() CONCURRENTLY
with respect to {almost} any other CONST operation on the same object.

That's not a problem for the standard -- in the standard, there is no
concurrency:-).

Seriously, of course, that is a general problem. In the case of string,
it is explicitly desired, but I see nothing in the standard forbidding
an implementation of any standard class from using mutable members. And
anything which uses mutable members, or casts away const, potentially
has this problem.

It looks like there's one more thing that authors have to document when
they write a class.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.