473,396 Members | 1,891 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

const char* vs string

Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).
I mean, in STL (http://www.sgi.com/tech/stl/hash_map.html) I see:

hash_map<const char*, int, hash<const char*>, eqstrmonths;
months["january"] = 31;

I think it is for the use in calls like function("my string"), but, is
it really necessary to define funcion(const char*) besides
function(const string &) in my public member functions?

I have read that the compiler does too much temporaries variables in
such cases, but is it true?

And what about in:

string mystring = "my string" + string1 + " is " + string2;

or in:

cout << string << " hello" << string2 << " my name is " << string3;

Thanks.

Jun 1 '07 #1
14 13598
Javier wrote:
Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).
Seldom.

The only real reason is interfacing with C code.
I mean, in STL (http://www.sgi.com/tech/stl/hash_map.html) I see:

hash_map<const char*, int, hash<const char*>, eqstrmonths;
months["january"] = 31;

I think it is for the use in calls like function("my string"), but, is
it really necessary to define funcion(const char*) besides
function(const string &) in my public member functions?

I have read that the compiler does too much temporaries variables in
such cases, but is it true?

And what about in:

string mystring = "my string" + string1 + " is " + string2;

or in:

cout << string << " hello" << string2 << " my name is " << string3;
What about them? I don't see how these link to your question.

--
Ian Collins.
Jun 1 '07 #2
On 1 jun, 12:12, Ian Collins <ian-n...@hotmail.comwrote:
Javier wrote:
Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).

Seldom.

The only real reason is interfacing with C code.
I mean, in STL (http://www.sgi.com/tech/stl/hash_map.html) I see:
hash_map<const char*, int, hash<const char*>, eqstrmonths;
months["january"] = 31;
I think it is for the use in calls like function("my string"), but, is
it really necessary to define funcion(const char*) besides
function(const string &) in my public member functions?
I have read that the compiler does too much temporaries variables in
such cases, but is it true?
And what about in:
string mystring = "my string" + string1 + " is " + string2;
Does the compiler create temporaries in this case? Is it important? I
mean, is it better to write?:

string mystring = "my string";
mystring += string1;
mystring += " is ";
mystring += string2;

than:

string mystring = "my string" + string1 + " is " + string2;
>
or in:
cout << string << " hello" << string2 << " my name is " << string3;
Same question.
>
What about them? I don't see how these link to your question.

--
Ian Collins.
Thanks.

Jun 1 '07 #3
Javier wrote:
>>
string mystring = "my string" + string1 + " is " + string2;

Does the compiler create temporaries in this case? Is it important? I
mean, is it better to write?:

string mystring = "my string";
mystring += string1;
mystring += " is ";
mystring += string2;

than:

string mystring = "my string" + string1 + " is " + string2;
Yes the second version does create temporaries and additional copies (tho
RVO might reduce some there). However, the second version is clearer than
the first one, seems more natural and unless you do that thousands of times
per second it shouldn't matter the additional cost (ie unless your code
profiling points this as a source of bottleneck). Also I think that in the
future with rvalue references and move semantics that overhead will be
eliminated anyway.

--
Dizzy

Jun 1 '07 #4
Javier wrote:
string mystring = "my string" + string1 + " is " + string2;
Does this even compile? I wouldn't expect it to.
Jun 1 '07 #5
Noah Roberts wrote:
Javier wrote:
>string mystring = "my string" + string1 + " is " + string2;

Does this even compile? I wouldn't expect it to.
Why not? The operator+(const char*, const std::string&) is defined.

Regards,

Zeppe
Jun 1 '07 #6
Javier wrote:
Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).
Almost never. The only reason I've ever used it when I needed
read/write access to a fixed-size raw buffer of chars that were
copied across processors using MPI without construction/destruction.

The other reasons could be "to be able to compile the program
with a really ancient C++ compiler which does not recognize string"
and "to show people how nasty bugs appear when using char*" <eg>.

HTH,
- J.
Jun 2 '07 #7
Javier wrote:
in which cases is it better the use of "const char*" to "string" (or
even const string &).
I would say that "const char*" is ok when you really have
compile-time constant strings, especially if you don't really need
to know their size.

Example:

const char* const KEYWORDS[] =
{ "keyword1", "keyword2", "keyword3", ... };

These are just compile-time constants which are not modified during
the execution of the program, so I would say that it's not really
necessary to have them as std::strings. If at some point you really
need to do some handling with those, it's pretty trivial to create
a std::string from them, like: std::string keyword = KEYWORDS[1];

Jun 2 '07 #8
void doSomething(std::string& param)
{

}
....

doSomething("DoThat");

doSomething will certainly call std::string constructor, alloc memory,
copy de contents, deallocate and its destructor will do something else
if it has some reference counter...

Why do that if "DoThat" will be stored in the data segement??? I am
not an expert but I am pretty sure you have a performance overhead
which is the price for the convenience...

So, is it never recommended using [const] char* instead of
std::string? I think "never" should be changed to "never if
performance doesn't matter".

Jose Ricardo
Jun 2 '07 #9
On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
Javier wrote:
Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).

Seldom.

The only real reason is interfacing with C code.
Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all). This is frequently a surprise to many C++
developers, but Scott Meyers and others give this topic a good
treatment in their various books (sorry, I don't have them on hand at
the moment, but one of the Effective C++/STL books I think). In short,
unless you can guarantee that your code is being compiled with exactly
the same compiler version as the library you are calling and that you
are using exactly the same compiler flags, then the only types safe to
use in the shared library's interface are POD types and pointers (but
it would be potentially unsafe to dereference these pointers).

So for the original poster's question, const char* will always be
portable and is safe to use in a library interface, whereas
std::string might or might not be safe depending on the compiler and
flags used. In real world code, we've found that this does matter and
we have defined our interfaces accordingly. YMMV.

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia
Jun 3 '07 #10
Craig Scott wrote:
On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Javier wrote:
>>Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).
Seldom.

The only real reason is interfacing with C code.

Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all).
Precisely correct in tha tthe Standard doesn't mention shared libraries.
Therefore the C++ standard does not guarantee that const char* is safe
to use anywhere in a shared library's interface either.
Jun 3 '07 #11
Craig Scott wrote:
On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Javier wrote:
>>Hello,
in which cases is it better the use of "const char*" to "string" (or
even const string &).
Seldom.

The only real reason is interfacing with C code.

Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all). This is frequently a surprise to many C++
developers, but Scott Meyers and others give this topic a good
treatment in their various books (sorry, I don't have them on hand at
the moment, but one of the Effective C++/STL books I think). In short,
unless you can guarantee that your code is being compiled with exactly
the same compiler version as the library you are calling and that you
are using exactly the same compiler flags, then the only types safe to
use in the shared library's interface are POD types and pointers (but
it would be potentially unsafe to dereference these pointers).
The same applies to any C++ linkage function as well. If you want to
have maximum compatibility, you have to stick to extern "C" linkage
functions, or choose a compiler that guarantees ABI compatibility.

--
Ian Collins.
Jun 3 '07 #12
On Jun 3, 2:44 pm, Craig Scott <audiofana...@gmail.comwrote:
On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
Javier wrote:
in which cases is it better the use of "const char*" to "string" (or
even const string &).
Seldom.
The only real reason is interfacing with C code.
Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all).
Strictly speaking, that's true for int as well. If all you're
counting on is what the C++ standard says, then you can't count
on int working in a dynamically linked object either.
This is frequently a surprise to many C++
developers, but Scott Meyers and others give this topic a good
treatment in their various books (sorry, I don't have them on hand at
the moment, but one of the Effective C++/STL books I think). In short,
unless you can guarantee that your code is being compiled with exactly
the same compiler version as the library you are calling and that you
are using exactly the same compiler flags, then the only types safe to
use in the shared library's interface are POD types and pointers (but
it would be potentially unsafe to dereference these pointers).
Not even that: you can't be sure at all about any struct, since
padding may depend on compiler options. For that matter, you
can't be sure about long---I've had the byte order of a long
change from one version of the compiler to the next, and you
certainly can't be sure about pointers, whose size depends on
compiler options.

In practice, there will be a set of options you can play with,
over a set of versions of the compiler.
So for the original poster's question, const char* will always be
portable and is safe to use in a library interface,
Except when the size of a pointer depends on a compiler option
(the usual case today, where all of the platforms I know support
both 32 and 64 bit pointers).

In fact, you're never really portable. The library supplier
should specify the restrictions, but in general, using
std::string entails no more risk than using any other struct.
whereas
std::string might or might not be safe depending on the compiler and
flags used. In real world code, we've found that this does matter and
we have defined our interfaces accordingly.
In the real world, we use std::string and std::vector without
problems, over a variety of compilers and systems.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 3 '07 #13
Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all).

Strictly speaking, that's true for int as well. If all you're
counting on is what the C++ standard says, then you can't count
on int working in a dynamically linked object either.
Fair enough.

This is frequently a surprise to many C++
developers, but Scott Meyers and others give this topic a good
treatment in their various books (sorry, I don't have them on hand at
the moment, but one of the Effective C++/STL books I think). In short,
unless you can guarantee that your code is being compiled with exactly
the same compiler version as the library you are calling and that you
are using exactly the same compiler flags, then the only types safe to
use in the shared library's interface are POD types and pointers (but
it would be potentially unsafe to dereference these pointers).

Not even that: you can't be sure at all about any struct, since
padding may depend on compiler options. For that matter, you
can't be sure about long---I've had the byte order of a long
change from one version of the compiler to the next, and you
certainly can't be sure about pointers, whose size depends on
compiler options.
Um, I believe I said exactly the same compiler version and flags. If
you use the same settings on the same compiler for the same platform,
you should get the same byte order, padding, pointer size, etc.

In practice, there will be a set of options you can play with,
over a set of versions of the compiler.
So for the original poster's question, const char* will always be
portable and is safe to use in a library interface,

Except when the size of a pointer depends on a compiler option
(the usual case today, where all of the platforms I know support
both 32 and 64 bit pointers).
Agreed. If you change a compiler option which causes a different
pointer size, you should expect things to explode. ;) I think the
main point is to know what compiler and flags were used to build the
shared library you want to use. It is then your responsibility to use
compatible flags for your own code.

In fact, you're never really portable. The library supplier
should specify the restrictions, but in general, using
std::string entails no more risk than using any other struct.
Unless different modules have their own memory heap (we have
encountered situations where some do). Then you run the risk of having
memory allocated in one module and then when you resize the string,
vector, etc in another module the memory needs to be freed in that
module and BOOM! Even if memory is always allocated/deallocated from
the one heap, having std::string, std::vector or any other container
in the interface prevents you from doing some cool stuff like use an
alternate STL implementation in your own code (such as STLport for
improved error checking). But "cool stuff" is just that, not
necessarily "required stuff". ;)

>
whereas
std::string might or might not be safe depending on the compiler and
flags used. In real world code, we've found that this does matter and
we have defined our interfaces accordingly.

In the real world, we use std::string and std::vector without
problems, over a variety of compilers and systems.
More power to you. For us, we've had bad experiences doing this with
one particular third party library we have to use (customer
requirement, library is the industry standard). We make heavy use of
std::string, std::vector within modules, we just avoid making them
part of the exposed interface. It's a bit of a pain, but until the C++
standard defines an ABI all compilers must adhere to, we have little
choice. Unfortunately, my understanding is that this has been pushed
out beyond the next draft.

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia

Jun 4 '07 #14
On Jun 4, 1:23 pm, Craig Scott <audiofana...@gmail.comwrote:
Actually, it can also matter for C++ code. If you are using shared
libraries, then you need to be aware that the C++ standard does not
guarantee that std::string is safe to use anywhere in a shared
library's interface (it mentions absolutely nothing about shared
libraries at all).
Strictly speaking, that's true for int as well. If all you're
counting on is what the C++ standard says, then you can't count
on int working in a dynamically linked object either.
Fair enough.
But of course, we all count on a little bit more from time to
time:-).
This is frequently a surprise to many C++
developers, but Scott Meyers and others give this topic a good
treatment in their various books (sorry, I don't have them on hand at
the moment, but one of the Effective C++/STL books I think). In short,
unless you can guarantee that your code is being compiled with exactly
the same compiler version as the library you are calling and that you
are using exactly the same compiler flags, then the only types safe to
use in the shared library's interface are POD types and pointers (but
it would be potentially unsafe to dereference these pointers).
Not even that: you can't be sure at all about any struct, since
padding may depend on compiler options. For that matter, you
can't be sure about long---I've had the byte order of a long
change from one version of the compiler to the next, and you
certainly can't be sure about pointers, whose size depends on
compiler options.
Um, I believe I said exactly the same compiler version and flags. If
you use the same settings on the same compiler for the same platform,
you should get the same byte order, padding, pointer size, etc.
If you use the same settings on the same compiler for the same
platform, you also have the same version of the standard
library.

Different compilers make different guarantees with regards to
"binary compatibility", but if binary compatability is
guaranteed between the different options, versions, etc., then
there should be no problem with the standard library either. If
it's not, on the other hand, you're likely to have problems with
POD struct's, pointers and---it happened once to me---even
longs or double. The standard library is part of the compiler,
and is covered by the sane "binary compatability" guarantees as
the rest.
In practice, there will be a set of options you can play with,
over a set of versions of the compiler.
So for the original poster's question, const char* will always be
portable and is safe to use in a library interface,
Except when the size of a pointer depends on a compiler option
(the usual case today, where all of the platforms I know support
both 32 and 64 bit pointers).
Agreed. If you change a compiler option which causes a different
pointer size, you should expect things to explode. ;) I think the
main point is to know what compiler and flags were used to build the
shared library you want to use. It is then your responsibility to use
compatible flags for your own code.
In fact, you're never really portable. The library supplier
should specify the restrictions, but in general, using
std::string entails no more risk than using any other struct.
Unless different modules have their own memory heap (we have
encountered situations where some do).
As far as I know, that never occurs under Unix, and only if you
don't take the proper precautions under Windows. (On the other
hand, I'm not sure who has to take the precautions: the user, or
the supplier of the DLL.) But that's a larger problem: you
can't free memory in one DLL that was allocated in another. Not
using components from the standard library isn't enough to avoid
problems.
Then you run the risk of having
memory allocated in one module and then when you resize the string,
vector, etc in another module the memory needs to be freed in that
module and BOOM! Even if memory is always allocated/deallocated from
the one heap, having std::string, std::vector or any other container
in the interface prevents you from doing some cool stuff like use an
alternate STL implementation in your own code (such as STLport for
improved error checking). But "cool stuff" is just that, not
necessarily "required stuff". ;)
I'm very sceptical about swapping the standard library. It's
part of the compiler, and you never know how much knowledge of
its implementation is built into the compiler.
whereas
std::string might or might not be safe depending on the compiler and
flags used. In real world code, we've found that this does matter and
we have defined our interfaces accordingly.
In the real world, we use std::string and std::vector without
problems, over a variety of compilers and systems.
More power to you. For us, we've had bad experiences doing this with
one particular third party library we have to use (customer
requirement, library is the industry standard). We make heavy use of
std::string, std::vector within modules, we just avoid making them
part of the exposed interface. It's a bit of a pain, but until the C++
standard defines an ABI all compilers must adhere to, we have little
choice. Unfortunately, my understanding is that this has been pushed
out beyond the next draft.
The C++ standard will never define an ABI, since this is, by its
very nature, platform specific.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 4 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Hans | last post by:
Hello, Why all C/C++ guys write: const char* str = "Hello"; or const char str = "Hello";
7
by: al | last post by:
char s = "This string literal"; or char *s= "This string literal"; Both define a string literal. Both suppose to be read-only and not to be modified according to Standard. And both have...
8
by: andrew.fabbro | last post by:
In a different newsgroup, I was told that a function I'd written that looked like this: void myfunc (char * somestring_ptr) should instead be void myfunc (const char * somestring_ptr) ...
5
by: Jae | last post by:
Real(const string &fileName) { FILE * myInputFile = fopen(fileName, "rt"); ..... fclose(myInputFile);
3
by: dstevel | last post by:
The signature for strtol is: strtol( const char*, char**, int) So.. if we start with a passed "const char*" (pointer to const char), then we can't create a non-const char pointer pointer to...
3
by: Rick Helmus | last post by:
Hello all In a few classes I have overloaded functions for C style strings and STL strings like this class SomeClass { void f(const char *s); void f(const std::string &s); };
2
by: Adrian | last post by:
Hi, In a header file I tried const char *someval="this is a test"; which is included all over the place and I get linker errors about multiple defines. Why is this not folded when const char...
20
by: liujiaping | last post by:
I'm confused about the program below: int main(int argc, char* argv) { char str1 = "abc"; char str2 = "abc"; const char str3 = "abc"; const char str4 = "abc"; const char* str5 = "abc";
9
by: Peithon | last post by:
Hi, This is a very simple question but I couldn't find it in your FAQ. I'm using VC++ and compiling a C program, using the /TC flag. I've got a function for comparing two strings int...
5
by: Bob Doe | last post by:
I have a const static object. What is the right syntax to get a reference to the std::vector within the std::map variable?: class MyObj { public: ... std::map<std::string,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.