Connecting Tech Pros Worldwide Forums | Help | Site Map

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

Tom Smith
Guest
 
Posts: n/a
#1: Oct 3 '06
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

Frederick Gotham
Guest
 
Posts: n/a
#2: Oct 3 '06

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


Tom Smith posted:
Quote:
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
Marcus Kwok
Guest
 
Posts: n/a
#3: Oct 3 '06

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


Tom Smith <not_giving_out_on@use.netwrote:
Quote:
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.
Quote:
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
loufoque
Guest
 
Posts: n/a
#4: Oct 3 '06

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


Tom Smith wrote:
Quote:
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.

Gavin Deane
Guest
 
Posts: n/a
#5: Oct 4 '06

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



Tom Smith wrote:
Quote:
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.
Quote:
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

Tom Smith
Guest
 
Posts: n/a
#6: Oct 4 '06

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


Gavin Deane wrote:
Quote:
Tom Smith wrote:
<snip>

I am assured that casting away the constness of
Quote:
Quote:
>the return value of std::string::c_str() is an Error according to the Standard.
>
<snip snippety snip>
Quote:
Quote:
>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
Closed Thread


Similar C / C++ bytes