CS253: Software Development with C++

Fall 2018

Casting

See this page as a slide show

CS253 Casting

Caution

Overview

C-style casting

In C, casting worked like this:

float f = 3.14;
unsigned char *p = &f;
printf("%02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
c.c: In function 'main':
c.c:2: warning: initialization of 'unsigned char *' from incompatible pointer type 'float *'
c3 f5 48 40
float f = 3.14;
unsigned char *p = (unsigned char *) &f;
printf("%02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
c3 f5 48 40

This works in C++, but don’t. Detect with g++ -Wold-style-cast.

Constructor “casting”

This isn’t really casting, but sure is similar:

int n;
n = int(3.14);
cout << "n is " << n << '\n';
n is 3

Of course, an actual programmer would just do this, even though a fussy compiler might issue a warning:

int n = 3.14;
cout << "n is " << n << '\n';
n is 3

With absolute power comes bad code

The problem with C-style casting is that it’s too powerful. It’s an “anything goes” sort of operation:

long l = (long) "Krypto the Superdog";
cout << l << '\n';
4196616

C++ casting

In C++, it was decided to break up the vast power of the C-style cast into separate tools:

const_cast

char *p = "☹";
cout << p;
c.cc:1: warning: ISO C++ forbids converting a string constant to 'char*'
☹

That failed, because p is type char *, whereas "☹" is type const char[] or const char *.

const_cast

const_cast<type>(value) removes constness. You have to specify the new type, but it must be the original type with const added.

char *p = const_cast<char *>("☺");
cout << p;

const_cast

However, const_cast can only change constness, not type:

const double *p = const_cast<const double *>("☹");
cout << p;
c.cc:1: error: invalid const_cast from type 'const char*' to type 'const 
   double*'

Similarly, for references.

static_cast

static_cast<type>(value): usual conversions

double d = 3.15;
int i = static_cast<int>(d);
cout << i;
3
int i = static_cast<int>("123");
cout << i;
c.cc:1: error: invalid static_cast from type 'const char [4]' to type 'int'

dynamic_cast

dynamic_cast<type>(value): object type conversion

class Base {
  public:
    virtual void foo() { }
};
class Derived : public Base { };

Base b, *bp = &b;
Derived *dp = dynamic_cast<Derived *>(bp);
if (dp == nullptr)
    cout << "Conversion failed.\n";
else
    cout << "Conversion succeeded.\n";
Conversion failed.

reinterpret_cast

reinterpret_cast<type>(value): go nuts

double avo = 6.022e23;

long l = reinterpret_cast<long>(&avo);
cout << l << endl;

int n = *reinterpret_cast<int *>(&avo);
cout << n << endl;

int *p = reinterpret_cast<int *>(42);
cout << "Goodbye, cruel world: " << *p << endl;
140727947684064
-195565037
SIGSEGV: Segmentation fault

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-08-26T13:45

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building