views:

244

answers:

4

Which is better for string literals, standard string or character array?

I mean to say for constant strings, say

const char name[] = "so"; //or to use 
const string name = "so";
+2  A: 

You should use what is more appropriate for you. If no special requirements I'd use std::string because it do all memory work.

For string literals, I'd use const char*. The reason against const char[] is that you could use const char* to initialize another constant. Check the following code:

const char str1[] = "str1";
const char* str11 = "str11";

const char str2[] = str1;    // <<< compile error
const char* str22 = str11;   // <<< OK

String literals has static storage duration (according to 2.13.4/2) so pointer const char* will be valid until the completion of the program.

Kirill V. Lyadvinsky
And is faster in many STL implementations thanks to a copy on write mechanism if yoou use the same strings in many different places, what also makes it easier to use than plain C strings. Beside this if you need to support many languages I would rather use std::wstring.
jdehaan
@jdehaan: I'd be surprised if there are (m)any std library implementations (not STL implementations, as `std::string` wasn't part of the STL) out there which still do COW. In MT environments this usually turns into a pessimization. I think small string optimization (small strings aren't allocated on the heap. but on the stack) is what is commonly favoured now.
sbi
Copy on write is being removed (if still present) in most implementations. It has problems in multithreaded environments, as some operations that seem thread-safe from the user point of view (they refer to different std::string's) may not be thread safe. Consider a string being copied with each copy passed onto different threads for modification. Each thread has it's own string, no shared objects, but in fact there can be a race condition in the 'copy-on-write' internal implementation. Adding a locking mechanism into the library turns it into slower than a plain implementation in many cases.
David Rodríguez - dribeas
@sbi, @dribeas, thanks for the hint, I indeed still use an older implementation... I do my never projects using .NET. I see I have to refresh my knowledge on modern STL implementations. Thanks.
jdehaan
@jdehaan, @sbi In any case, passing a string literal directly to `string::string` will copy it and will not use COW, assuming the compiler doesn't have a special internal type for string literals besides `const char[]` and an STL which jibes.
Potatoswatter
+1  A: 

What are you doing with it? What do your methods expect?

const char is lighter in storage, but doesn't have the power of std::string, or the safety when using it. However, if you have a lot of C APIs, it may be the more judicious choice.

std::string would be the preferred option.

Yann Ramin
.c_str() is your friend :)
JPvdMerwe
@JPvdMerwe: theatrus is correct. If all you're doing is passing a constant string to functions requiring a `const char*` there is no point in using `std::string` / `.c_str()`. A `const` array of `char` has no constructor call cost and can be passed directly to the functions which makes it cheaper to construct and cheaper to pass to functions than a `std::string`.
Charles Bailey
Yes for string literals, I agree completely, no point wasting your processor time.
JPvdMerwe
+5  A: 

For string literals, and only for string constants that come from literals, I would use const char[]. The main advantage of std::string is that it has memory management for free, but that is not an issue with string literals.

It is the actual type of the literal anyway, and it can be directly used in any API that requires either the old C style null terminated strings or the C++ strings (implicit conversion kicks in). You also get a compile time size implementation by using the array instead of the pointer.

Now, when defining function interfaces, and even if constants are intented to be passed in, I would prefer std::string rather than const char*, as in the latter case size is lost, and will possibly need to be recalculated.

Out of my own experience. I grew old of writting .c_str() on each and every call to the logging library (that used variable arguments) for literal strings with info/error messages.

David Rodríguez - dribeas
A: 

I tend to favour const std::string over const char * for string literals. Because passing string literals into functions taking const std::string & will silently create string everytime they are called instead of just one. However if I mainly use the literal with functions expecting a const char * I will use that instead.

I tend to favour std::string for apis.

Of course if I am using unicode I use std::wstring and wchar_t.

iain