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

const char* to char* conversion

P: n/a
Hi!

I've got this:

string str1;
char * str2;
....
str1 = "whatever";
....
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Thanks in advanced!

Jun 19 '06 #1
Share this Question
Share on Google+
34 Replies


P: n/a
Perro Flaco wrote:
I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.


No, it's not OK. And, no, there is no "better" way to do it. It's bad
no matter how you try doing it. Why do you think you need that?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 19 '06 #2

P: n/a
Perro Flaco posted:

str2 = (char *)str1.c_str();

str2 = const_cast<char*>( str1.c_str() );
I think it's valid just so long as you don't use "str2" to alter the data
(but I'm open to correction).
--

Frederick Gotham
Jun 19 '06 #3

P: n/a
Frederick Gotham wrote:
Perro Flaco posted:

str2 = (char *)str1.c_str();

str2 = const_cast<char*>( str1.c_str() );
I think it's valid just so long as you don't use "str2" to alter the
data (but I'm open to correction).


What if you use 'str1' to alter the data?
Jun 19 '06 #4

P: n/a

Perro Flaco wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.

2) You must not change str1 at all, until you have finished doing
things with str2. Any change to str1 could (and probably will) make the
pointer str2 invalid.

Chris

Jun 19 '06 #5

P: n/a
Not sure about your intention, but if you want to play it safe adding a
const with str2 will help.

string str1;
const char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Victor Bazarov wrote:
Frederick Gotham wrote:
Perro Flaco posted:

str2 = (char *)str1.c_str();

str2 = const_cast<char*>( str1.c_str() );
I think it's valid just so long as you don't use "str2" to alter the
data (but I'm open to correction).


What if you use 'str1' to alter the data?


Jun 19 '06 #6

P: n/a
Because there are other functions that need "char*" as input, so I get
errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to char*.
Any advice?

Thanks!
Victor Bazarov ha escrito:
Perro Flaco wrote:
I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.


No, it's not OK. And, no, there is no "better" way to do it. It's bad
no matter how you try doing it. Why do you think you need that?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Jun 19 '06 #7

P: n/a
Ok, now I see what's going on :)

Thank you!
Azumanga ha escrito:
Perro Flaco wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.

2) You must not change str1 at all, until you have finished doing
things with str2. Any change to str1 could (and probably will) make the
pointer str2 invalid.

Chris


Jun 19 '06 #8

P: n/a

Victor Bazarov wrote:
Frederick Gotham wrote:
Perro Flaco posted:

str2 = (char *)str1.c_str();

str2 = const_cast<char*>( str1.c_str() );
I think it's valid just so long as you don't use "str2" to alter the
data (but I'm open to correction).


What if you use 'str1' to alter the data?


Nothing more nor less than what happens without the const_cast afaik.
The pointer you got from c_str() may or may not get hosed.

Jun 19 '06 #9

P: n/a

Azumanga wrote:
Perro Flaco wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.


And the fact that they accept char* instead of const char* indicates
that they will.

Jun 19 '06 #10

P: n/a
Noah Roberts wrote:
Azumanga wrote:
Perro Flaco wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.


And the fact that they accept char* instead of const char* indicates
that they will.


Exactly. I see nothing but disaster in store for wanting to cast away
this particular const.
Jun 19 '06 #11

P: n/a
In article <11**********************@g10g2000cwb.googlegroups .com>,
"Perro Flaco" <fa****************@gmail.com> wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Thanks in advanced!


A better way to do it:

string str1;
vector<char> str2;

str1 = "whatever";

copy( str1.begin(), str1.end(), back_inserter( str2 ) );
Jun 19 '06 #12

P: n/a
Daniel T. wrote:
In article <11**********************@g10g2000cwb.googlegroups .com>,
"Perro Flaco" <fa****************@gmail.com> wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Thanks in advanced!


A better way to do it:

string str1;
vector<char> str2;

str1 = "whatever";

copy( str1.begin(), str1.end(), back_inserter( str2 ) );


You forgot:

str2.push_back('\0');
APICall(&str2[0]);
Jun 19 '06 #13

P: n/a
Perro Flaco wrote:
Because there are other functions that need "char*" as input, so I get
errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to char*.
Any advice?

When some function need a 'char*' (as opposed to 'const char*') as an input,
this usually means one of two things:

1) The function needs to modify the data pointed by that 'char*' pointer. In
this can what you are trying to do is simply useless, because strings of
'std::string' type cannot be modified through the pointer returned by 'c_str()'.

Functions that modify the data pointed by 'char*' parameter are not compatible
with 'std::string' at all. The only safe way around is to convert the
'std::string' to a standalone modifiable zero-terminated C-style string, pass it
to the function and then convert the results back to 'std::string'.

2) The function parameter is declared improperly. In other words, the function
doesn't really need to modify the data, i.e. it doesn't really need a 'char*'
and a 'const char*' would work just as well. The better way to resolve the
problem in this case would be to change the function's parameter declaration
from 'char*' to the more appropriate 'const char*', assuming this is possible.
Otherwise, the 'const_cast' of 'c_str()' result to 'char*' type (mentioned by
others) would work, but it is rather ugly.

--
Best regards,
Andrey Tarasevich
Jun 19 '06 #14

P: n/a
Daniel T. wrote:
In article <11**********************@g10g2000cwb.googlegroups .com>,
"Perro Flaco" <fa****************@gmail.com> wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not
sure if I'm doing the rigth thing, so I hope you can help me with
this.

Thanks in advanced!


A better way to do it:

string str1;
vector<char> str2;

str1 = "whatever";

copy( str1.begin(), str1.end(), back_inserter( str2 ) );


If str2 is not used up until here, the form

string str1;
..
str1 = "whatever";
..
vector<char> str2(str1.begin(), str1.end());

is actually better, IMO. It can't be helped, of course, if 'str2' is
a member of the same class as 'str1'.

We have, however, already seen the reason why the OP needed the pointer
and vector is not a good substitute.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 19 '06 #15

P: n/a
Yes, this is what I've done. We don't need the "char*" and a "const
char*" would do a perfect work.

Thanks!
Andrey Tarasevich ha escrito:
Perro Flaco wrote:
Because there are other functions that need "char*" as input, so I get
errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to char*.
Any advice?

When some function need a 'char*' (as opposed to 'const char*') as an input,
this usually means one of two things:

1) The function needs to modify the data pointed by that 'char*' pointer. In
this can what you are trying to do is simply useless, because strings of
'std::string' type cannot be modified through the pointer returned by 'c_str()'.

Functions that modify the data pointed by 'char*' parameter are not compatible
with 'std::string' at all. The only safe way around is to convert the
'std::string' to a standalone modifiable zero-terminated C-style string, pass it
to the function and then convert the results back to 'std::string'.

2) The function parameter is declared improperly. In other words, the function
doesn't really need to modify the data, i.e. it doesn't really need a 'char*'
and a 'const char*' would work just as well. The better way to resolve the
problem in this case would be to change the function's parameter declaration
from 'char*' to the more appropriate 'const char*', assuming this is possible.
Otherwise, the 'const_cast' of 'c_str()' result to 'char*' type (mentioned by
others) would work, but it is rather ugly.

--
Best regards,
Andrey Tarasevich


Jun 19 '06 #16

P: n/a

Perro Flaco wrote:
Yes, this is what I've done.


"this"??

Jun 19 '06 #17

P: n/a
"Sgt. York" <yo**@frontlines.org> wrote in message
news:m9******************************@scnresearch. com...
Noah Roberts wrote:
Azumanga wrote:
Perro Flaco wrote:
Hi!

I've got this:

string str1;
char * str2;
...
str1 = "whatever";
...
str2 = (char *)str1.c_str();

Is this ok? Is there any other better way to do the same? I'm not sure
if I'm doing the rigth thing, so I hope you can help me with this.

Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.


And the fact that they accept char* instead of const char* indicates
that they will.


Exactly. I see nothing but disaster in store for wanting to cast away
this particular const.


I agree. Unfortunately I use a library with a header which is not const
correct. I've been trying to get the library developer to fix his const
correctness, but so far to little luck.

I wind up using things like:

somefunction( blah, blah, const_cast<char*>( MyString.c_str() ), blah );
and it's quite ugly and I don't like it, but have little choice until he
fixes his library (or I hack the header).

Which brings up a question that is probably OT for this newsgroup. If a
program is linking to a .lib and using a header, can the header be changed
to const correctness even if the calls in the .dll aren't const correctness?
That is, if it is known for a fact that the .dll won't change the data of a
char*, can changing the header to a const char * cause problems? If this is
OT (which it is) just ignore it please.
Jun 20 '06 #18

P: n/a
Jim Langston wrote:
[..]
If a program is linking to a .lib and using a header, can the header
be changed to const correctness even if the calls in the .dll aren't
const correctness?
Only if the linkage of those functions is "C". Otherwise, the type of
the arguments is part of the type of the function, and likely its name.
That is, if it is known for a fact that the .dll
won't change the data of a char*, can changing the header to a const
char * cause problems? If this is OT (which it is) just ignore it
please.


Yes, it can cause problems. And, yes, it is slightly OT because it's
implementation- and platform-specific.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 20 '06 #19

P: n/a
Jim Langston wrote:
"Sgt. York" <yo**@frontlines.org> wrote in message
news:m9******************************@scnresearch. com...
Noah Roberts wrote:
Azumanga wrote:
Perro Flaco wrote:
> Hi!
>
> I've got this:
>
> string str1;
> char * str2;
> ...
> str1 = "whatever";
> ...
> str2 = (char *)str1.c_str();
>
> Is this ok? Is there any other better way to do the same? I'm not sure
> if I'm doing the rigth thing, so I hope you can help me with this.
>
Depends what you want to do. In your current situation, you can do the
following:

1) You can pass str2 to functions that expect a char*. However it is
important that nothing changes the string at all.
And the fact that they accept char* instead of const char* indicates
that they will.

Exactly. I see nothing but disaster in store for wanting to cast away
this particular const.


I agree. Unfortunately I use a library with a header which is not const
correct. I've been trying to get the library developer to fix his const
correctness, but so far to little luck.

I wind up using things like:

somefunction( blah, blah, const_cast<char*>( MyString.c_str() ), blah );
and it's quite ugly and I don't like it, but have little choice until he
fixes his library (or I hack the header).


I would go out of my way to avoid this. I would use a temporary despite
the performance hit.

-York
Jun 20 '06 #20

P: n/a
this -->

The function parameter is declared improperly. In other words, the
function
doesn't really need to modify the data, i.e. it doesn't really need a
'char*'
and a 'const char*' would work just as well. The better way to resolve
the
problem in this case would be to change the function's parameter
declaration
from 'char*' to the more appropriate 'const char*', assuming this is
possible.
Otherwise, the 'const_cast' of 'c_str()' result to 'char*' type
(mentioned by
others) would work, but it is rather ugly.
Noah Roberts ha escrito:
Perro Flaco wrote:
Yes, this is what I've done.


"this"??


Jun 20 '06 #21

P: n/a

Andrey Tarasevich wrote:
Perro Flaco wrote:
Because there are other functions that need "char*" as input, so I get
errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to char*.
Any advice?

When some function need a 'char*' (as opposed to 'const char*') as an input,
this usually means one of two things:

1) The function needs to modify the data pointed by that 'char*' pointer. In
this can what you are trying to do is simply useless, because strings of
'std::string' type cannot be modified through the pointer returned by 'c_str()'.

Functions that modify the data pointed by 'char*' parameter are not compatible
with 'std::string' at all. The only safe way around is to convert the
'std::string' to a standalone modifiable zero-terminated C-style string, pass it
to the function and then convert the results back to 'std::string'.

2) The function parameter is declared improperly. In other words, the function
doesn't really need to modify the data, i.e. it doesn't really need a 'char*'
and a 'const char*' would work just as well. The better way to resolve the
problem in this case would be to change the function's parameter declaration
from 'char*' to the more appropriate 'const char*', assuming this is possible.
Otherwise, the 'const_cast' of 'c_str()' result to 'char*' type (mentioned by
others) would work, but it is rather ugly.


There is a third reason:

Some older "C" APIs require char* even though the string will not be
modified. When this is the case, a const_cast will suffice.

As example, take for instance the vxWorks function lptDevCreate:

Declaration as stated in their documentation.
STATUS lptDevCreate
(
char * name, /* name to use for this device */
int channel /* physical channel for this device (0 - 2) */
);

Now, when calling this (over which you have no control), there is
nothing wrong with doing the following:

void createLptDevice( const std::string& name, eChannelType channel )
{
STATUS result(
lptDevCreate( const_cast<char*>(name.c_str()),
static_cast<int>(channel) ) );
//...if( STATUS == ERROR ) throw etc...
}

I must mention that I would in such cases write wrapper functions (like
the one above) that only do the const_cast in one place. Often related
wrappers would reside in a wrapper class that becomes responsible for
the resource.

Kind regards,

Werner

Jun 20 '06 #22

P: n/a
Sgt. York wrote:
Jim Langston wrote:
I wind up using things like:

somefunction( blah, blah, const_cast<char*>( MyString.c_str() ),
blah ); and it's quite ugly and I don't like it, but have little
choice until he fixes his library (or I hack the header).


I would go out of my way to avoid this. I would use a temporary
despite the performance hit.


What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;

I hate it when the library is not const-correct and I have to resort
to this...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 20 '06 #23

P: n/a

Victor Bazarov wrote:
What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;

I don't agree here (see my other post). Also refer to Scott Meyers'
Item 21 of Effective C++ (the incorreclty declared strlen example,
where he states its OK to use const_cast in this/that situation).
I hate it when the library is not const-correct and I have to resort
to this...
Yes me too, but what you did is in some cases an overkill (when you
know for a fact that the function will not modify the string, despite
it not being const correct). This is most often very obvious. When not,
I would take your route - I would try to get rid of memory by scoping
though - would use boosts scoped_array typically.

boost::scoped_array<char> p( new char[MyString.size()+1] );
std::copy( MyString.begin(), MyString.end(), p.get() );
//personally, I hate memcpy because of it lack of type safety...
p[MyString.size()] = '\0';
someFunction( p.get() );
//No need to delete, but you'd know...

....Of course, knowing that someFunction was in actual fact strlen,
declared in BadLib, this would become.

strlen( const_cast<char*>(MyString.c_str() ); //:-)


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Jun 20 '06 #24

P: n/a

Perro Flaco wrote:
Noah Roberts ha escrito:
Perro Flaco wrote:
Yes, this is what I've done.
"this"??


[top posting fixed]
The function parameter is declared improperly. In other words, the
function
doesn't really need to modify the data, i.e. it doesn't really need a
'char*'
and a 'const char*' would work just as well. The better way to resolve
the
problem in this case would be to change the function's parameter
declaration
from 'char*' to the more appropriate 'const char*', assuming this is
possible.
Otherwise, the 'const_cast' of 'c_str()' result to 'char*' type
(mentioned by
others) would work, but it is rather ugly.


I see. I couldn't tell wtf you were talking about because of your top
posting. You would be more understandable if you stopped doing that.

http://lipas.uwasa.fi/~ts/http/quote.html

Jun 20 '06 #25

P: n/a
Victor Bazarov wrote:
Sgt. York wrote:
Jim Langston wrote:
I wind up using things like:

somefunction( blah, blah, const_cast<char*>( MyString.c_str() ),
blah ); and it's quite ugly and I don't like it, but have little
choice until he fixes his library (or I hack the header).

I would go out of my way to avoid this. I would use a temporary
despite the performance hit.


What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;

I hate it when the library is not const-correct and I have to resort
to this...

V


Yes, that's what I meant, the temporary in this case being the variable
"p". Bad choice of wording on my part, since temporary means something
else in c++.
Jun 20 '06 #26

P: n/a
werasm wrote:
Victor Bazarov wrote:
What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;


I don't agree here (see my other post). Also refer to Scott Meyers'
Item 21 of Effective C++ (the incorreclty declared strlen example,
where he states its OK to use const_cast in this/that situation).
I hate it when the library is not const-correct and I have to resort
to this...


Yes me too, but what you did is in some cases an overkill (when you
know for a fact that the function will not modify the string, despite
it not being const correct). This is most often very obvious. When not,
I would take your route - I would try to get rid of memory by scoping
though - would use boosts scoped_array typically.


How is this "most often very obvious?" I'm given a compiled library and
a header file. How do I used that to determine that "very obviously" a
non-const pointer is not being used to modify memory?
Jun 20 '06 #27

P: n/a
werasm wrote:

Some older "C" APIs require char* even though the string will not be
modified. When this is the case, a const_cast will suffice.

As example, take for instance the vxWorks function lptDevCreate:

Declaration as stated in their documentation.
STATUS lptDevCreate
(
char * name, /* name to use for this device */
int channel /* physical channel for this device (0 - 2) */
);

I'm always very wary of passing the pointer from c_str() to any library
function, const or not. That's because of this:

"Requires: The program shall not alter any of the values stored in the
array. Nor shall the program treat the returned value as a valid
pointer value after any subsequent call to a non-const member function
of the
class basic_string that designates the same object as this."
If that library function stores off the pointer, or passes it around,
it may become invalid due to affects elsewhere in the code.

The best idea all-around is to make a copy of the thing.

Brian
Jun 20 '06 #28

P: n/a

Default User wrote:
If that library function stores off the pointer, or passes it around,
it may become invalid due to affects elsewhere in the code.


Well, you better know things like that anyway. If it stores it
somewhere or passes it off then you still have similar problems because
you need to know when you can delete it.

char* is just plain problematic. Nothing you do will make it safe or
easy to work with.

Jun 20 '06 #29

P: n/a
"Sgt. York" <yo**@frontlines.org> wrote in message
news:ha******************************@scnresearch. com...
werasm wrote:
Victor Bazarov wrote:
What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;


I don't agree here (see my other post). Also refer to Scott Meyers'
Item 21 of Effective C++ (the incorreclty declared strlen example,
where he states its OK to use const_cast in this/that situation).
I hate it when the library is not const-correct and I have to resort
to this...


Yes me too, but what you did is in some cases an overkill (when you
know for a fact that the function will not modify the string, despite
it not being const correct). This is most often very obvious. When not,
I would take your route - I would try to get rid of memory by scoping
though - would use boosts scoped_array typically.


How is this "most often very obvious?" I'm given a compiled library and a
header file. How do I used that to determine that "very obviously" a
non-const pointer is not being used to modify memory?


A function such as
void display_text( char * Text, int X, int Y );

Even though it's not const correct, it better not change the char array.
That should be fairly obvious unless the library developer is really out of
whack.
Jun 21 '06 #30

P: n/a
Jim Langston wrote:
"Sgt. York" <yo**@frontlines.org> wrote in message
news:ha******************************@scnresearch. com...
werasm wrote:
Victor Bazarov wrote:

What "temporary" would you use? The proper way, of course, is to
allocate necessary memory in free store, copy the string contents
there, and then give the pointer to the function:

char* p = new char[MyString.size() + 1];
memcpy(p, MyString.data(), MyString.size() + 1);
somefunction( blah, blah, p );
delete[] p;

I don't agree here (see my other post). Also refer to Scott Meyers'
Item 21 of Effective C++ (the incorreclty declared strlen example,
where he states its OK to use const_cast in this/that situation).

I hate it when the library is not const-correct and I have to resort
to this...
Yes me too, but what you did is in some cases an overkill (when you
know for a fact that the function will not modify the string, despite
it not being const correct). This is most often very obvious. When not,
I would take your route - I would try to get rid of memory by scoping
though - would use boosts scoped_array typically.

How is this "most often very obvious?" I'm given a compiled library and a
header file. How do I used that to determine that "very obviously" a
non-const pointer is not being used to modify memory?


A function such as
void display_text( char * Text, int X, int Y );

Even though it's not const correct, it better not change the char array.
That should be fairly obvious unless the library developer is really out of
whack.


Exactly. I am not confident from reading a function's name alone that
it does not modify my pointer. I would consider the developer "out of
whack" for not declaring the pointer const in the parameter list to
begin with if there is no intent to modify the memory. Some of the
Win32 API functions spring to mind ...
Jun 21 '06 #31

P: n/a

Sgt. York wrote:
How is this "most often very obvious?" I'm given a compiled library and
a header file. How do I used that to determine that "very obviously" a
non-const pointer is not being used to modify memory?


Well, in the case of strlen, the documentation might simply state this.
In other cases such as those mentioned, the documentation also states
this. The legacy library simply has not changed with the times, and is
still usable. It may also be obvious from experience, of course.

Many libraries existed and are used that were created in pre-const
days, unfortunately. You have two options, either pay the performance
penalty or, if you know the library - do the const_cast. The important
thing is, know why you are doing what you are doing. If you don't need
the performance gain, then use the heap.

Regards,

W

Jun 21 '06 #32

P: n/a

Default User wrote:
werasm wrote:
Declaration as stated in their documentation.
STATUS lptDevCreate
(
char * name, /* name to use for this device */
int channel /* physical channel for this device (0 - 2) */
);

If that library function stores off the pointer, or passes it around,
it may become invalid due to affects elsewhere in the code.


Yes, true. But then making a copy of the thing won't suffice - only a
literal or global would (perhaps a global const std::string or static -
in which case the const_cast would once again be required). Most of the
old API functions with parameters called "name" expected literals. The
only problem that you may have is that the function does not
necessarily complete synchronously. If the function has a result
indicating completion, such as strlen - or the above mentioned one, it
is safe to assume that the usage of the parameter has completed.

The fact remains, that for these unfortunate (const incorrect) APIs,
whether you create memory on the heap, or whether you const_cast c_str,
or whether you use a buffer on the stack (which is what I would prefer
over heap, BTW) - in all these cases you are likely to get failure.
Using literals or global/static consts then become your only option,
but what if your name is borne from your instance (dynamic), and is a
concatenation of various literals. Then we go back to:

1. Create copy on heap
- whack could delete it at worst void foo( char* name) { delete p;
/*fooled ya*/ }.
- whack could send it to another context (PostMessage...).
- whack could overindex...
- etc
2. Create copy on stack
- All the above still apply - obviously with undefined results.
3. Use a string.
- All the above still applies.
- In addition to this the string may not be modified - impossible for
local string BTW.
- If the string is modified by the function, then behaviour is
undefined - yes.

Alas...
For these unfortunate functions, I try to understand what the parameter
is used for, and then act accordingly. If it is used synchronously
only, and only performs reading (which I derive from the names of
parameters, return type and documentation etc), then I'm willing to go
for the const_cast. If not, well - then I'll be carefull of other
options mentioned too, as they are also error prone - especially in a
RoundRobin scheduling OS.

All said, if you're given a gun but you haven't seen one before, you
can shoot yourself! For this reason, to any newbies - I advise you
being very careful of such API's - using the most conservative
approach. const_cast is certainly less conservative.

Regards,

Werner

Jun 21 '06 #33

P: n/a

Perro Flaco wrote:
Because there are other functions that need "char*" as input, so I get
errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to char*.
Any advice?

Thanks!


The correct solution is to use function overloading:

#include <iostream>

void f(char *)
{
std::cout << "char *" << std::endl;
}

void f(char const * p)
{
std::cout << "char const *" << std::endl;
f(const_cast<char *>(p));
}

int main()
{
char const * x = "Hello";
f(x);
char * p = "Hello";
f(p);
}

Jun 21 '06 #34

P: n/a
u.********@gmail.com wrote:
Perro Flaco wrote:
Because there are other functions that need "char*" as input, so I
get errors when I do: str1.c_str()

I would like to convert a string to a char*, or a const char* to
char*. Any advice?

Thanks!
The correct solution is to use function overloading:

#include <iostream>

void f(char *)
{
std::cout << "char *" << std::endl;
}

void f(char const * p)
{
std::cout << "char const *" << std::endl;
f(const_cast<char *>(p));
}

int main()
{
char const * x = "Hello";
f(x);
char * p = "Hello";


While this is kinda OK for an example like yours, if I saw it in my
student's work, I'd definitely lowered the grade. Initialising
a pointer to non-const char with a literal is allowed in C++ when it
really ought to be disallowed (and all who did that in their code
had to fix their code). A [much] better way would be

char p[] = "Hello";
f(p);
}


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 21 '06 #35

This discussion thread is closed

Replies have been disabled for this discussion.