Wednesday, October 30, 2013

Why string's c_str()? [Overloading const char *()]

Newsgroup: comp.lang.c++

Subject: Why string's c_str()? [Overloading const char *()]

From: DSF <notavalid@...>

Date: Wed, 30 Oct 2013 15:00:26 -0400



Hello group!



I have been using/writing my own string class for some time now. A

while back, I discovered the wonderful ability to overload const char

*. I was now able to use my string anywhere I could use const char *.

But... I had always wondered why the STL string class uses c_str()

instead of overloading const char *(). My first thought on the

subject is that it frees the string class to store the string in any

manner the coder chooses. One option would be to use the format of

[length of string][string]. But then I started reading articles

online stating that overloading const char *() is a bad idea because

it can allow unintended implicit conversions. Of course, most of

these articles used the typical overkill terms such as "dangerous" and

"evil", etc. Without going into detail of the specific dangers and

evils.



I came upon a discussion at the site below that intrigued me.



http://www.dreamincode.net/forums/topic/260662-operator-const-char-and-operator-caveats-with-overloads/



Since the site thread is fairly old, I decided to ask here.



I've reposted a small section here. (I hope they don't mind.)



//start

D.I.C Lover

Re: operator const char* and operator[] - caveats with overloads?



Posted 21 December 2011 - 02:18 PM

The problems will arise from ambiguous conversions. In C++, if you

have a statement with two different types, the compiler will try to

find a cast for one or the other so that the statement can be

evaluated. Now when you start adding conversions like this, you can't

prepare for every possible use of your class. Because of this, someone

who doesn't fully understand the language might try to use your class

in such a way that ambiguous conversions occur. The fact that the

designers of the std::string class left out a conversion operator, is

enough of an explanation to tell me that it should be avoided.



View Postmonkey_05_06, on 21 December 2011 - 03:52 PM, said:

What would be considered "accidental" or "unintended" conversions to

char*?



Things that come to mind are.



01 String a, b;

02 if (a==B) {}

03 if (a=="str") {}

04 if ("str"==a) {}

05 if ("str"!=a) {}

06 if (a > B) {}

07 if (a <= B) {}

08 if ("str" < a) {}

09 *a;

10 (a + 5);



All these things will suddenly just compile, but none of these will do

what you expect from a String class.



What Karel-Lodewijk said is exactly what I am talking about. Without a

conversion operator, most of those statements will not compile. With a

conversion operator they WILL compile, but not do what you expected.

If you feel like chasing around hard to find bugs, then leave it in

there, if not just add a function like the std::string::c_str().

//end





The examples above along with "none of these will do what you expect

from a String class" aroused my curiosity. Except for 09 and 10, I

was pretty certain the rest would do what I expect them to.



So I compiled the above with my string class, adding the harmless

getch() (wait for a keypress) within all of the {} so the whole thing

wouldn't be optimized away and to test the result of the if

statements. I also ran it with string 'a' initialized to "str".



Every single one of the first 8 did exactly what I expected.



9 did nothing (of course), but walking through the assembly code

confirmed it returned a pointer to the first character of string 'a'.

I added a char c; statement, then c = *a; then a printf using 'c' and

it worked. Funny, the compiler won't optimize *a; away, but with the

statement c=*a; it will optimize away the c= if you don't use the 'c'

leaving the *a code intact.



10 I wasn't sure about. Of course, it also did nothing on the

surface, but below it got a pointer to 'a', added 5 to it and returned

the resulting pointer. An overrun with a = "" or a = "str", but

that's not the point.



So what is the "danger" of overloading * (or in the case of above *

and [])? Everything I've written so far has worked as I expected, and

it's very convenient and looks more elegant than the alternatives when

one needs to pass a const char * to an API call, etc.



"'Later' is the beginning of what's not to be."

D.S. Fiscus







via Usenet Forums - Usenet Search,Free Usenet - comp.lang.c++ http://www.pocketbinaries.com/usenet-forums/showthread.php?118599-Why-string-s-c_str()-Overloading-const-char-*()&goto=newpost

View all the progranning help forums at:

http://www.pocketbinaries.com/usenet-forums/forumdisplay.php?128-Coding-forums

No comments:

Post a Comment