By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,148 Members | 1,342 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,148 IT Pros & Developers. It's quick & easy.

On std::string::c_str() and const_cast<char*>

P: n/a
I hardly dare ask this given the furore in another thread over strings and
const... My problem is this. I am assured that casting away the constness of
the return value of std::string::c_str() is an Error according to the Standard.
But I need to pass it to a function (in an old and unpleasant C library, ugh)
which takes an ordinary char*. What should I do? Is it really necessary to make
a fresh copy of the string?

(I'm not asking this from a performance point of view - the string is rarely
likely to be over 20 characters, and in any case it's certainly not a bottleneck
- but just from an aesthetics one: it's already annoying enough that std::string
doesn't gracefully give me a way of getting a plain char* to its data. (Or am I
wrong?))

Thanks in advance,
Tom
Oct 3 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Tom Smith posted:
I hardly dare ask this given the furore in another thread over strings
and const... My problem is this. I am assured that casting away the
constness of the return value of std::string::c_str() is an Error
according to the Standard. But I need to pass it to a function (in an
old and unpleasant C library, ugh) which takes an ordinary char*. What
should I do? Is it really necessary to make a fresh copy of the string?

Does the unpleasant C library function alter the data? If not, then simply
cast away the constness.

If it does, then you have to consider:

(1) Is it okay to alter the data at the address specified by c_str?

If so,

(1.a) Just cast away the constness and let it be altered.

If not,

(1.b) You'll have to make a copy.

--

Frederick Gotham
Oct 3 '06 #2

P: n/a
Tom Smith <no***************@use.netwrote:
I hardly dare ask this given the furore in another thread over strings and
const... My problem is this. I am assured that casting away the constness of
the return value of std::string::c_str() is an Error according to the Standard.
As far as I know, as long as you don't ever try to modify the contents
of the string pointed to by c_str(), you should be fine casting away its
constness.
But I need to pass it to a function (in an old and unpleasant C library, ugh)
which takes an ordinary char*. What should I do? Is it really necessary to make
a fresh copy of the string?
As long as you are 100% totally sure that the function won't try to
modify the char* string, then you should be OK.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Oct 3 '06 #3

P: n/a
Tom Smith wrote:
it's already
annoying enough that std::string doesn't gracefully give me a way of
getting a plain char* to its data. (Or am I wrong?))
All existing implementations use contiguous memory.
It may be a requirement in the next standard also.

So if you really need to you could just code using the assumption that
std::string is contiguous.

Oct 3 '06 #4

P: n/a

Tom Smith wrote:
I hardly dare ask this given the furore in another thread over strings and
const... My problem is this. I am assured that casting away the constness of
the return value of std::string::c_str() is an Error according to the Standard.
No. It is perfectly legitimate to cast away the const using const_cast.
What is not legitimate (read: undefined behaviour) is to then try and
modify the now apparently non-const data.
But I need to pass it to a function (in an old and unpleasant C library, ugh)
which takes an ordinary char*. What should I do? Is it really necessary to make
a fresh copy of the string?
Depends on what the library function does. If it modifies the data then
you do need to make a copy. The std::string class encapsulates its data
and makes available facilities to modify its data through its public
interface. std::string is not designed to be able to handle anything
outside directly modifying the data outside the scope of its public
interface.

However, many functions that take a C-style string passed as a char* do
not and are never intended to modify the data. Such functions (which
may be C or C++) are written with char* rather than const char* in the
signature for a number of reasons, e.g.

1 The function is a legacy function, written before const existed or
was widely supported
2 The programmer was careless in making the code const-correct
3 The programmer did not know of the existence of const

In a case where the parameter should logically be const, but happens
(e.g. for one of the reason above) not to be declared const, that is
exactly the situation const_cast is designed for. It allows you to keep
your code const-correct, by using const declarations and classes that
manage their own data, while still being able to interface with
const-incorrect legacy APIs.

Remember that a cast does not mean "I can't think of another way to
make this work. I hope it doesn't go wrong". A cast means "Dear
compiler, you won't like this code without a cast, but I know exactly
what I'm doing and why. I am casting off all the safety precautions you
usually give me and assuming full responsibility for the correct
behaviour of this code because in this case I know best".

There is no other way to tell the compiler that the API is incorrect
and should have been written to take a const char*, so if you really do
know best then tell the compiler that with a const_cast.

Gavin Deane

Oct 4 '06 #5

P: n/a
Gavin Deane wrote:
Tom Smith wrote:
<snip>

I am assured that casting away the constness of
>the return value of std::string::c_str() is an Error according to the Standard.
<snip snippety snip>
>But I need to pass it to a function (in an old and unpleasant C library, ugh)
which takes an ordinary char*. What should I do?

Depends on what the library function does. If it modifies the data then
you do need to make a copy. The std::string class encapsulates its data
and makes available facilities to modify its data through its public
interface. std::string is not designed to be able to handle anything
outside directly modifying the data outside the scope of its public
interface.
<more snippage>

Thanks very much Gavin & all other repliers for your advice: very helpful indeed.

- Tom
Oct 4 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.