static_cast and ( )

Hello everyone, im pretty new to c++ and i wanted to print out
the address of a char sequence,
and i heard in order to do that, i would first need to convert the
char sequence to an integer value so i did

1
2
3
4
5
6
7
8
9
10
11
  #include <iostream>
#include <string>

using namespace std;

int main(){
char str[5] = "asdf";

cout << hex <<(int)str;

return 0;}


and it ran perfectly fine, however, ive heard that in c++
it is more preferable to use static_cast over ( ) so i decided to take that into consideration and created

1
2
3
4
5
6
7
8
9
10
11
  #include <iostream>
#include <string>

using namespace std;

int main(){
char str[5] = "asdf";

cout << hex <<static_cast<int>(str);

return 0;}


however, when i do that id get

|9|error: invalid static_cast from type 'char [5]' to type 'int'|

this error message

Im really confused and if anyone can tell me why this is happening and tell me the difference with static cast and ( ) it will be greatly appreciated. thanks
In C++ we have reinterpret_cast which does the same thing as ( )
so is that different from static_cast?
the book that i seem to own tells me that static_cast is the c++ equivalent of ( ), so how are two different?
Last edited on
A C-style cast expression may be evaluated as any one of: a const_cast, a static_cast,
a static_cast followed by a const_cast, a reinterpret_cast, a reinterpret_cast followed by a const_cast.

These possible C++ casts are examined in the above order; the first one that can be satisfied is selected.


1
2
3
4
const char str[5] = "asdf";

// print out the address 
cout << static_cast<const void*>( str ) ;
modoran wrote:
In C++ we have reinterpret_cast which does the same thing as ( )


Ehh...

C style cast is different depending on the context. It can be reinterpret_cast, static_cast, or const_cast. Though usually it's the same as static_cast.


The difference between casting types (and arguably the reason C++ casts were created) is noticable when you get to polymorphism.

For the below examples... let's assume you have the following classes:

1
2
3
4
5
// P1 and P2 are polymorphic parent classes
// C is a child class which inherits from both of them
class P1 {  virtual ~P1() { } };
class P2 {  virtual ~P2() { } };
class C : public P1, public P2 { };


The different casts:

reinterpret_cast will take the binary data and merely ('stupidly') reinterpret it as another type. This cast basically does nothing other than change the type.

example:
1
2
C obj;
P2* ptr = reinterpret_cast<P2*>(&obj);


Here... '&obj' and 'ptr' will be binary identical... but 'ptr' may or may not be a valid pointer (you should assume it isn't and should not attempt to dereference it). Since the address of &obj may not actually point to P2 data... having a P2 pointer pointing to that address may be invalid.

reinterpret_cast has limited practical uses and should generally be avoided unless you are doing something very specific, and/or are very sure of what you are intending to do.

static_cast will cast between types in an "intelligent" way, making binary adjustments as necessary. Some examples:

1
2
P2* ptr = new C;  // create a C object, but with a P2 pointer
C* cptr = static_cast<C*>(ptr);


Here, static cast will [at compile time], examine the class hierarchy and make any necessary binary adjustments to 'ptr' in order for the resulting cptr to point to the necessary object. This may result in 'ptr' and 'cptr' not being binary identical.... but it will ensure that the address is correct assuming 'ptr' actually does point to a C object.

Another example:

1
2
float foo = 5.0f;
int bar = static_cast<float>(foo);


The thing to note with this example is that floating point variables and integral variables are stored very different in memory. It you were to do a straight binary copy (ie: a reinterpret), bar would not be 5, but would probably be several thousand.

So static_cast here does a more intelligent cast, where it determines the integral equivilent of 5 and makes necessary binary adjustments. The end result is that both foo and bar will be 5, even though they will not be binary identical.


dynamic_cast is similar to the first example of static_cast.. where it examines class hierarchies and makes the necessary changes to pointers of polymorphic types. The only difference is it does this at runtime rather than at compile time. This way, it ensures that the cast is actually valid.

Example:
1
2
3
P2* orig = new P2;
C* stat = static_cast<C*>(orig);
C* dyn = dynamic_cast<C*>(orig);


Here... static_cast will assume 'orig' actually points to a C object and will return a pointer pointing to where that object would be in memory. However, since in this example, it DOESN'T point to a C object (it only points to a P2)... the result is that 'stat' will be a bad pointer.

On the other hand... dynamic_cast will examine 'orig' at runtime, see that it doesn't actually point to a C object, realize it's a bad cast, and will make 'dyn' be a null pointer rather than a bad pointer.

The general rule of thumb is:
- Use static_cast only if you are absolutely sure the pointer you have actually points to the desired type.
- Use dynamic_cast if there is any doubt as to whether or not the pointer points to the intended object.


const_cast Removes 'const' and/or 'volatile' qualifiers on types. This hardly ever has any practical use so I won't go into further details. If you find yourself using const_cast, you are probably doing something very, very wrong.

C-style cast... ie the (int) business... is a mish-mash of all of the above.

When it can do a const_cast, that's what it does
Otherwise if it can do a static_cast, that's what it does
Otherwise if it can do a reinterpret_cast, that's what it does

It all depends on the context. Since it's less verbose, less explicit, and therefore less safe than the C++ style casts, it's often avoided in favor of static_cast... even though static_cast requires more typing.
Thanks! It really helped
so can anyone tell me which one i should be using for the aforementioned code I wrote??
Is it recommended that I use the reinterpret_cast?
> Is it recommended that I use the reinterpret_cast?

No. Repeat:
1
2
3
4
const char str[5] = "asdf";

// print out the address 
cout << static_cast<const void*>( str ) ;



C-style cast
C++ cast expressions are attempted, one by one, in this order:
1. const_cast
2. static_cast (with extensions)
3. static_cast (with extensions) followed by a const_cast
4. reinterpret_cast
5. reinterpret_cast followed by a const_cast

The first cast expression that satisfies the bare syntactic requirements is selected, even if it can't be done (in which case, we get a compile-time error).

The gory details are here: http://en.cppreference.com/w/cpp/language/explicit_cast
thanks! now I understand
Topic archived. No new replies allowed.