CS253: Software Development with C++

Spring 2019

Casting

Show Lecture.Casting as a slide show.

CS253 Casting

Caution

Overview

C-style casting

In C, casting worked like this:

float f = 3.14;
unsigned int *p = &f;
printf("%08x", *p);
c.c: In function 'main':
c.c:2: warning: initialization of 'unsigned int *' from incompatible pointer type 'float *'
4048f5c3
float f = 3.14;
unsigned int *p = (unsigned int *) &f;
printf("%08x", *p);
4048f5c3

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

That’s the address of the string (array of char) as a decimal number, a thing of questionable value. Hope it fits into a long!

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*'

This way, if you see const_cast, you know that it’s only removing constness.

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;
140721191733888
-195565037
SIGSEGV: Segmentation fault

When casting is not appropriate.

string s = "3.1415926535";
double d = stod(s);
cout << "π ≅ " << d << '\n'; 
s = "42";
int i = stoi(s, nullptr, 16);
cout << s << " base 16 = " << i << " base 10\n";
π ≅ 3.14159
42 base 16 = 66 base 10

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2019-03-15T22:59

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