473,244 Members | 1,573 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,244 software developers and data experts.

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

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
5 9151
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
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
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

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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Matt Garman | last post by:
What is the "best" way to copy a vector of strings to an array of character strings? By "best", I mean most elegantly/tersely written, but without any sacrifice in performance. I'm writing an...
17
by: Karl Ebener | last post by:
Hi! I asked a similar question before but then changed everything to using char-Arrays instead of the string class, but I would rather not do this again. So, does anyone know of a...
8
by: Earl Purple | last post by:
On VC++.NET it is implemented like this static int __cdecl compare ( const _Elem *_First1, const _Elem *_First2, size_t _Count ) { // compare [_First1, _First1 + _Count) with [_First2, ...)...
13
by: Richard | last post by:
vector<char*> m_Text; m_Text.resize(1); char* foo = "FOO"; char* bar = "BAR"; char* foobar = (char*)malloc(strlen(foo) + strlen(bar) + 1); if (foobar) { strcpy(foobar, foo); strcat(foobar,...
4
by: lada77 | last post by:
All, Just wondering if one of you very helpful guru's out there could comment on some odd behaviour I am seeing. I'm betting it is something obvious but I am not experienced enough to tell...
24
by: Marcus Kwok | last post by:
Hello, I am working on cleaning up some code that I inherited and was wondering if there is anything wrong with my function. I am fairly proficient in standard C++ but I am pretty new to the .NET...
4
by: Jim Langston | last post by:
I'm using a function like this: char TextBuffer; jGet_DropDown_Selected_Text( cc.ddSex, TextBuffer); Where the function is filling in the text buffer. I don't have access to the actual...
1
by: Dancefire | last post by:
Hi, everyone, I'm trying to use std::codecvt<to do the encoding conversion. I am using following code for encoding conversion between wchar_t string and char string(MBCS). I am not sure am I...
7
by: puzzlecracker | last post by:
I need to be able to use map<char, T*>, I can make it std::map<std::string, T*>, however, Key is passed by char, hence I would need to call c_str() all the time. What do you suggest?
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

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.