strings vs char*'s

Started by
8 comments, last by Antrim 18 years, 8 months ago
I've read Scott Meyers opinion on this (Effective C++), but still, virutally every book and tutorial I find uses char*'s instead of std::strings. I'm wondering if there is some reason for this, other than just personal preference? Is there some reason that a function should be passed or return a char* rather than a string*? Not that I can't get it to work either way...I'm just wondering the reason for the lack of string usage in game programming. Thanks for any input Antrim
Advertisement
I'm wondering if there is some reason for this, other than just personal preference?

As a general rule, ignorance and possibly misconceptions based on hearsay.

Is there some reason that a function should be passed or return a char* rather than a string?

Passing objects across library boundaries can become a complex affair. Giving a library a C interface increases its usability/portability.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
I suspect that many of the authors grew up with C and don't like change. Also, old habits die hard, i'm often surprised by the number of C++ developers who prefer printf() to cout.

One more thing, if you are noticing that the C++ book you are reading dedicates more space to creating dynamic C style arrays than C++ vectors, you might want to consider getting a different book.
A whole lot of material found on the net is just horrible. Either being way out of date originating before there even was a C++ standard or being just plain wrong.

Personally I think a book called "Accelerated C++" takes the right approach. Chapter 1 is "working with strings" and it uses std::string right away making no mention of C-strings. Pointers and arrays don't come until chapter 10, after iterators and containers.


// ville
When it comes to writing functions, I myself pass char*'ers, for the main reason that, if I want to pass a string, I simply pass MyString.c_str(), which basically achieves the same result. If I want to pass something different, I can without overloading/rewriting the function.

But when storing strings of text, I opt for std::string because of two reasons:

1) Neater
2) The template functions

The reason why most online tutorials don’t use the standard library is because it simply complicates the matter for most beginners, or the author doesn’t know much on the subject. But if you are paying a wad of cash for a book, I think it should contain at least the barebones of the standard library (IMHO "Accelerated C++" is a very good book). I also agree with Fruny, cross-library passing isn’t a great idea.
Quote:If I want to pass something different, I can without overloading/rewriting the function.


std::string has a constructor that takes a const char* meaning a char* can be implicitly converted to an std::string so taking a const std::string& should suffice in most situations, unless you want to modify the string in which case std::string& should be fine. The only time problems may arise if you want to pass an object which has a user defined conversion to char* or const char* but none to std::string.

Quote:rather than a string*


I'd suggest using references rather than pointers when dealing with std::string. If you want to return a string just return a straight std::string.
It's not simple or safe to pass what std::string::c_str() returns to a function accepting a char* parameter.

Personally I don't see the advantage of char const* arguments over std::string const& arguments. If it's a library meant to be used with C and C++ projects then sure, but if all of the codebase is C++ then where is the concrete gain?

Last I recall even the standard comitee was considering on putting a stop to the separation of streams and string, giving methods that accept std::string const&.


// ville
Ahhh, thanks for the replies. I especially hadn't thought about the portability issues when using std::strings as parameters or return values.

As for myself, even when reading books/tutorials and writing similar code, I generally use strings and vectors when I can instead of the other methods used by the authors. It's just that lately I've noticed that nearly all my resources were using char*s, writing their own linked lists, etc., so I was curious as to if there was some performance issue or anything else that I needed to be aware of.

Seems like it's mostly a combination of teaching new people without confusing them and not wanting to make the switch.

I am a bit confused about this though:
Quote:It's not simple or safe to pass what std::string::c_str() returns to a function accepting a char* parameter<


I was under the impression that c_str() is exactly what you wanted to call when passing a std::string to a function that accepts or expects a char*. But you say that passing std::string& or const std::string& is a better method?

Thanks again for all the replies,

Antrim
Quote:Original post by Antrim
I was under the impression that c_str() is exactly what you wanted to call when passing a std::string to a function that accepts or expects a char*. But you say that passing std::string& or const std::string& is a better method?


It's not a better method, it's actually the opposite of c_str(). A function that accepts a std::string& will accept a char*, so if *you* are designing the function interface, you should use a std::string& unless you know that it is not appropriate .

For example in a binary library interface for which I can't guarantee that the implementation of std::string I used in the library is going to be binary-compatible with the implementation you use in your program, so we need to agree on a common ground to pass text across the library boundary: char* which you and I both would immediately convert to our version of std::string as soon as we've received it (or as neede [smile]) and only convert back to char* if and when it needs to be passed back.
Passing 'opaque types' around is also a possibility: I declare (but do not define) a struct type in my library's header file, and have my library function create, pass around and destroy pointers to that type, which really are pointers to my std::string, but you don't know that. And now you don't need any conversions so you gain in performance (YAY!). And since all the creation/destruction/manipulation code is internal to the library, you never get nor need to see the definition for the struct (really the ultimate in encapsulation). So that means that, even though we may have different representations for std::string we could just use mine and my manipulation functions - granted, with a awkward C-style interface (you could create an object-oriented facade/bridge (q.v. Design Patterns) to alleviate that problem).
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Ah, ok...gotcha. Thanks for the clarification.

This topic is closed to new replies.

Advertisement