 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ryan Myers Guest
|
Posted: Sat Oct 04, 2003 4:28 pm Post subject: Defect Report: basic_string's const method c_str() can inval |
|
|
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
|
Posted: Sun Oct 05, 2003 6:11 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
"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
|
Posted: Sun Oct 05, 2003 6:54 pm Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
"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
|
Posted: Tue Oct 07, 2003 12:46 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
[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
|
Posted: Tue Oct 07, 2003 12:46 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
"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
|
Posted: Tue Oct 07, 2003 12:46 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
[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
|
Posted: Tue Oct 07, 2003 5:47 pm Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
[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
|
Posted: Wed Oct 08, 2003 7:20 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
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
|
Posted: Fri Oct 10, 2003 1:17 am Post subject: Re: Defect Report: basic_string's const method c_str() can i |
|
|
[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 |
|
 |
|
|
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
|
|