Re: casting from char* to const char*
On Mar 20, 1:40 pm, luca.pampar...@gmail.com wrote:
Hello,
What is the safe and recommended way to cast a char* to a const char*?
Can I simply do:
const char * dest = reinterpret_cast<const char *>(src);
NO!
or is there a C++ gotcha that I need to be aware of?
T * a;
T const * b = a; //always implicit for all types T
(Though see the C++ FAQ why this is not the same as
T ** a;
T const ** b = a; //will not compile for any type T
)
You do not need an explicit cast to go from pointer to pointer-to-
const, or pointer to const-pointer-to-nonconst. It can be done
implicitly.
You seem to be quite new to C++ and/or const. I would suggest learning
more C++, as basic stuff like your question is covered in all school
courses and all teach-yourself books.
Do not use reinterpret_cast. In almost all cases, using a
reinterpret_cast in C++ means another cast would suffice, either
implicit, static_cast, or dynamic_cast, that or your code has
undefined behavior. Read up on C and C++'s strict aliasing rule for
more information as to why most uses of reinterpret_cast which are not
other casts have undefined behavior.
Also, reinterpret_cast is usually not what you want for multiple
inheritance situations, so just avoid using it unless you really know
what you're doing, aka understand the strict aliasing rule. For
example, run the program
#include <iostream>
using namespace std;
struct A { int ax; };
struct B { int bx; };
struct C : A, B { int cx; };
int main()
{
C c;
c.ax = 0;
c.bx = 0;
c.cx = 0;
C * pc = & c;
{
B * pb = pc;
pb->bx = 1;
}
{
B * pb2 = reinterpret_cast<B*>(pc);
cout << pb2->bx << endl;
}
}
This program will not print what you think it will print. (It also has
undefined behavior.) The reason is that casting in C++ is not just
something used to appease the compiler and it's type checker. Casting
in C++ can result in changing the literal bit-value of the pointer.
reinterpret_cast is "I know what I'm doing. Just use the bit-value
here and interpret it as something else.", whereas to correctly cast
between related types in the general case can require changing the bit-
value of the pointer.
Finally, for similar reasons as reinterpret_cast, never use C-style
casts in C++ code, eg:
A * a = (A*) b;
Also, the C-style cast in C++ code is even more insidious and evil.
Take three different ways to do the same cast:
B * b = make_new_b();
A * a = (A*) b;
A * a = static_cast<A*>(b);
A * a = reinterpret_cast<A*>(b);
Here are some possible scenarios:
All 3 casts will compile to the same binary. (Situation: single
inheritance and the full definitions of the types are in scope.)
All 3 casts will compile. The C-style cast and the static_cast will
compile to the same binary, but the reinterpret_cast will compile to
different binary. (Situation: multiple inheritance, the full
definitions of the types are in scope, and luck as sometimes 3 will be
the same as 1 and 2, sometimes it won't.)
The C-style cast and reinterpret_cast will compile to the same binary.
The static_cast will not compile. (Situation: The types are forward
declared. The best part about this is that if later the full
definitions come into scope, like if someone added a header to another
header which your cpp includes, the behavior of the c-style cast can
silently change. THIS IS WHY YOU NEVER USE THE C-STYLE CAST IN C++
CODE.)
The reinterpret_cast will compile. The C-style cast and the
static_cast will not compile. (Situation 1: It's an ambiguous cast
from derived to base, multiple inheritance of the same base class, and
not virtually.) (Situation 2: It's a down cast going across virtual
inheritance.)
The short version is never use C-style casts in C++ code, ever. Ever.
I mean it. Use reinterpret_cast only if you understand the strict
aliasing rule and/or you want to write non-standard, platform
dependent code.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]