Topic: string -> const char* conversion operator
Author: jim brown <jimm@aol.com>
Date: 1996/11/15 Raw View
Valentin Bonnard wrote:
>
> > Poul Thomas Lomholt wrote:
>
> > Philip Gruebele wrote:
> > >
> > > I think that the 'string' class contains a slight oversight. It should
> > > have a conversion operator which returns a "const char*". This would be
> > > equivalent to calling c_str(), but easier in most cases. I can't seem
> > > to be able to find such an operator. Is there any reason for this?
> > >
> > Yes. That's because implicit conversion operators are considered
> > harmful. There has been a lot of discussion on this, and the
> > conclusion was to omit it! That's life.
I'd like to hear the full explanation for this myself. I find that my code
is becoming littered with calls to string::c_str(), for example, whenever I
have to pass a string to a C-style API which takes a parameter of type const
char *. Granted, implicit conversion can be bad, but usually we're
concerned about cases where the source and target types are not semantically
equivalent, right?
It's worth getting these little details right, even at this late date. The
old story that one is free to write replacements for these classes is no
longer tenable, in that we have to integrate our code with many other C++
class libraries and can't afford the overhead of redundant classes.
xxxxxxxxxxxxxxxxxx
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Graham Hughes <graham.hughes@resnet.ucsb.edu>
Date: 1996/11/16 Raw View
-----BEGIN PGP SIGNED MESSAGE-----
jim brown <jimm@aol.com> writes:
>I'd like to hear the full explanation for this myself. I find that my code
>is becoming littered with calls to string::c_str(), for example, whenever I
>have to pass a string to a C-style API which takes a parameter of type const
>char *. Granted, implicit conversion can be bad, but usually we're
>concerned about cases where the source and target types are not semantically
>equivalent, right?
Easy enough: strings can be created as temporaries. As such, I can
define a method
string foo ();
which will return a copy of a string object. Now, let's suppose that
strings implicitly went to const char *. Then,
const char * bar = foo();
will give bar something derived from the temporary foo() created. The
key here is that the temporary holds all the storage rights, and when it
goes away (which it will do at what might as well be a random time) bar
is left pointing to something that doesn't exist anymore.
Thus,
const char * foobar () {
return string("Can");
}
will probably core dump or something equivalent. This is not a good
thing. Now, c_str doesn't solve this problem, but it makes you think a
bit more about what you're doing.
- --
Graham Hughes (graham.hughes@resnet.ucsb.edu)
http://A-abe.resnet.ucsb.edu/~graham/ for HTML
``Unix is many things to many people, but | finger graham@A-abe.resnet
it's never been everything to anybody.'' | for PGP key
-----BEGIN PGP SIGNATURE-----
Version: 2.6.2
iQCVAwUBMo0TuSqNPSINiVE5AQHUJQQAmn/HY1bt87OIbTnLXYIZgYqVMOhVQTp1
sSZdRp82TR+JH0HjrIPwhgdCqYdH+aStObKAuHLIz2t+QXZUDFyz/AvcY3cr48A9
eRxC4u3LFIG63RDVXyOOerGgwLpfn+YK7oRfrJpbGF+KeF6678pPaP4QMb2hVJJy
MRNvHR1i8b4=
=vEUz
-----END PGP SIGNATURE-----
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "john (j.d.) hickin" <hickin@nortel.ca>
Date: 1996/11/16 Raw View
> > > Yes. That's because implicit conversion operators are considered
> > > harmful. There has been a lot of discussion on this, and the
> > > conclusion was to omit it! That's life.
>
> I'd like to hear the full explanation for this myself.
You may consult "The Annotated C++ Reference Manual", aka the ARM, , by
Margaret A. Ellis and Bjarne Stroustrup, Addison-Wesley, 1990 (later
editions are available as well), ISBN 0-201-51459-1.
Section 12.2 Temporary Objects has a very readable explanation of the problem
with an example string class. The conclusions drawn remain valid today, even
though the rules governing the timing of the destruction of compiler-generated
temporaries have substantially changed.
--
John Hickin Nortel Technology, Montreal, Quebec
(514) 765-7924 hickin@nortel.ca
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: 100653.2230@compuserve.com (Raoul De Kezel)
Date: 1996/11/16 Raw View
Graham Hughes <graham.hughes@resnet.ucsb.edu> wrote:
>jim brown <jimm@aol.com> writes:
>>I'd like to hear the full explanation for this myself. I find that my
>>code is becoming littered with calls to string::c_str(), for example,
>>whenever I have to pass a string to a C-style API which takes a
>>parameter of type const char *. Granted, implicit conversion can be
>>bad, but usually we're concerned about cases where the source and
>>target types are not semantically equivalent, right?
> Now, let's suppose that
>strings implicitly went to const char *. Then,
>const char * bar = foo();
>will give bar something derived from the temporary foo() created. The
>key here is that the temporary holds all the storage rights, and when it
>goes away (which it will do at what might as well be a random time) bar
>is left pointing to something that doesn't exist anymore.
I used extensively the Rogue Wave string class which has a const char
* conversion operator. While it is true that the conversion is
potentially dangereous, I don't remember having ever been actually
burned, mostly because I use exclusively strings in my code. But I do
remember numerous times where I didn't have to even remember whether
some third party function parameters were strings or const char *,
because the conversion was implicit.
So I've found that in practice the const char * conversion is quite
useful and not at all dangereous. People mixing strings and char * in
their code will probably have a different experience.
--- Raoul
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <pbecker@oec.com>
Date: 1996/11/18 Raw View
Raoul De Kezel wrote:
> I used extensively the Rogue Wave string class which has a const char
> * conversion operator. While it is true that the conversion is
> potentially dangereous, I don't remember having ever been actually
> burned, mostly because I use exclusively strings in my code. But I do
> remember numerous times where I didn't have to even remember whether
> some third party function parameters were strings or const char *,
> because the conversion was implicit.
>
> So I've found that in practice the const char * conversion is quite
> useful and not at all dangereous. People mixing strings and char * in
> their code will probably have a different experience.
I think this proves exactly what has been claimed: it is extremely
dangerous to call a function without bothering to understand what types
of arguments it takes. Please don't ever ask me to maintain code that
has been written by someone who is too lazy to take the time to
understand what they are doing.
-- Pete
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/18 Raw View
We implemented a string class years ago when we first started using c++.
I can remember getting 'burned' by the char*() conversion operator (it
was so long ago that const wasn't there yet and the ARM hadn't been published)
and writing a somewhat pointed letter which ended up in the hands of somebody
close to the compiler's development team. The reply gently persuaded me that
what was broken was the class design, not the programming language.
In those days compilers could destroy a compiler generated temorary 'as soon as
its value was taken' and there was a high probability of disaster. The rules
regarding the timing of the destruction of temporaries are much different now
and the type of bug that hit our code will no longer occur under the proposed
rules. Unfortunately there are other cases lurking. In essence, the new rules
have merely changed the probabilities of getting burned. While reduced (some
might say substantially reduced), the probabilities remain non-zero that you
will write code sufficiently compilicated to trigger a problem. With the
decreasing probability of triggering such problems, however, comes an
increasing probability that it will take a very long time to figure out what is
happening to you when you do get burned. It is better, in my opinion, to take
a conservative approach, and prevent the problem altogether.
As far as the Rogue Wave class is concerned, my advice is to be careful with
it.
Its developers seem to be patently aware that not all c++ implementations are
created equal. Here is an excerpt from cstring.h:
// Type conversion:
#ifndef RW_ZTC_TYPE_CONVERSION_BUG
operator const char*() const {return pref_->data();}
#endif
--
John Hickin Nortel Technology, Montreal, Quebec
(514) 765-7924 hickin@nortel.ca
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "john (j.d.) hickin" <hickin@nortel.ca>
Date: 1996/11/19 Raw View
Sorry, I was the author of this reply, so please direct any flames my way
and not to Steve Clamage!
I don't know how this happened. My only defense it that it seems to have
happened before.
--
John Hickin Nortel Technology, Montreal, Quebec
(514) 765-7924 hickin@nortel.ca
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1996/11/11 Raw View
Poul Thomas Lomholt wrote:
>
> Philip Gruebele wrote:
> >
> > I think that the 'string' class contains a slight oversight. It should
> > have a conversion operator which returns a "const char*". This would be
> > equivalent to calling c_str(), but easier in most cases. I can't seem to
> > be able to find such an operator. Is there any reason for this?
> >
> Yes. That's because implicit conversion operators are considered
> harmful. There has been a lot of discussion on this, and the
> conclusion was to omit it! That's life.
Are you sure ? Are you a member of the corresponding WG ?
I'm not so I'm just guessing:
It's clearly a design decision but what is consider harmfull ?
1) c_str
2) implicit conversions
(1) is obvious; *I* think (2) is false (I am stating my opinion, I am
*not* saying it's the opinion of anyone else.)
The reasoning could be:
1) c_str is dangerous [the string of THINK C had a c_str that froze()
the string, so after deletion the value was still usable:
string s;
const char* p = (s + "\n\n").c_str(); // OK
// p is valid until.... the end of the program
// or ?? delete[] p; ??
--end note], c_str is dangerous so it should not be implicit
(2) any implicit user defined conversion is bad so don't add this one
This could be the reason (same as auto_ptr) but if so why do
string(const char*), and auto_ptr(T*) exist ?
It would be really interresting to have a rationnal for the standard
(more up-to-date than D&E !).
--
Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Philip Gruebele" <philipg@bayarea.net>
Date: 1996/11/05 Raw View
I think that the 'string' class contains a slight oversight. It should
have a conversion operator which returns a "const char*". This would be
equivalent to calling c_str(), but easier in most cases. I can't seem to
be able to find such an operator. Is there any reason for this?
Regards
Philip Gruebele
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/05 Raw View
In article 7f40dbcd@philipg, "Philip Gruebele" <philipg@bayarea.net> writes:
>I think that the 'string' class contains a slight oversight. It should
>have a conversion operator which returns a "const char*". This would be
>equivalent to calling c_str(), but easier in most cases. I can't seem to
>be able to find such an operator. Is there any reason for this?
Type conversion operators are dangerous because they can lead to
unexpected conversions when you don't want or expect them. They
also introduce many more opportunities for ambiguous function calls.
Using a named function instead means you get the conversion when and
only when you explicitly ask for it. Using c_str instead of a type
conversion operator was a deliberate design decision.
---
Steve Clamage, stephen.clamage@eng.sun.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <pbecker@oec.com>
Date: 1996/11/06 Raw View
Philip Gruebele wrote:
>
> I think that the 'string' class contains a slight oversight. It should
> have a conversion operator which returns a "const char*". This would be
> equivalent to calling c_str(), but easier in most cases. I can't seem to
> be able to find such an operator. Is there any reason for this?
Yes. It is errorprone. For example:
void f( const char * );
string s1( "Hello " );
string s2( "world!" );
f( s1+s2 ); // legal if string has a const char * conversion
const char *str = s1+s2; // also legal if string has a const char *
conversion
f( str ); // uh oh... str no longer points to anything valid
Now, that's ordinarily a perfectly reasonable code transformation,
changing a temporary to a named variable, but in this case it leads to
trouble because there are really two temporaries. The decision to
include c_str() and not have a conversion to const char * makes it
harder to do this accidentally.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: ken@digitas.org (Ken Shan)
Date: 1996/11/06 Raw View
Philip Gruebele (philipg@bayarea.net) wrote:
> I think that the 'string' class contains a slight oversight. It should
> have a conversion operator which returns a "const char*". This would be
> equivalent to calling c_str(), but easier in most cases. I can't seem to
> be able to find such an operator. Is there any reason for this?
I think the reason is because it's easy to shoot yourself with:
string a;
string b;
// ...
// ... put stuff into a and b
// ...
// ... in some other part of the code:
const char *s = a + b;
cout << s; // this is wrong! the buffer pointed to by s
// is invalid since the end of the previous statement.
--
blue | Ken; Shan, Chung-chieh; Sian7, Tiong1-kiat8; ccshan@fas.harvard.edu.
() | Your code today becomes the mind tomorrow: Your plan its means,
/\ | your dream its ends, your ideal its elegance. Hack on.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: andrewb@graphsoft.com (Andrew C. Bell)
Date: 1996/11/06 Raw View
"Philip Gruebele" <philipg@bayarea.net> wrote:
>I think that the 'string' class contains a slight oversight. It should
>have a conversion operator which returns a "const char*". This would be
>equivalent to calling c_str(), but easier in most cases. I can't seem to
>be able to find such an operator. Is there any reason for this?
I'll answer this this time, having asked it before... would you
moderators like me to format an answer for the FAQ?
[Yes, I think that would be a good idea. -mod]
suppose you have a function which returns a string:
string foo();
and somewhere in your code, you do
const char *bar = foo();
once the foo() completes, the temporary string gets destroyed, and bar
points to a deallocated pointer.
Particularly bad is that foo() might start out returning a pointer to
a global string, and then get changed to return a string (when the
global approach proves too limited); a bug gets introduced without
warning.
It's worth typing a few extra characters to avoid this. It's also
under consideration but unlikely, last I heard, that the standard may
have explicit conversion operators, so you could put in the cast to
convert it. This would be nice for some template uses.
Personally, I think the string class should also support << for all
the basic types, so I can do
template <class Out> Out &
operator<<(Out &out,const Point3D &point)
{
return out << point.X() << "," << point.Y() << ","
point.Z();
}
but I don't miss the const char * operator at all.
Andrew Bell
andrewb@graphsoft.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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Poul Thomas Lomholt <davinci@image.dk>
Date: 1996/11/07 Raw View
Philip Gruebele wrote:
>
> I think that the 'string' class contains a slight oversight. It should
> have a conversion operator which returns a "const char*". This would be
> equivalent to calling c_str(), but easier in most cases. I can't seem to
> be able to find such an operator. Is there any reason for this?
>
Yes. That's because implicit conversion operators are considered
harmful.
There has been a lot of discussion on this, and the conclusion was to
omit it! That's
life.
Regards from
Poul Thomas
> Regards
>
> Philip Gruebele
> ---
> [ 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 ]
> [ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
> [ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
> [ Comments? mailto:std-c++-request@ncar.ucar.edu ]
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Philip Gruebele" <philipg@bayarea.net>
Date: 1996/11/07 Raw View
Thank you all for the responses. I can certainly see why the decision for
c_str() was made....
Regards
Philip Gruebele
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]