C++ Typecasting Part 1

Typecasting is the concept of converting the value of one type into another type. For example, you might have a float that you need to use in a function that requires an integer.

Implicit conversion

Almost every compiler makes use of what is called automatic typecasting. It automatically converts one type into another type. If the compiler converts a type it will normally give a warning. For example this warning: conversion from ‘double’ to ‘int’, possible loss of data.

The problem with this is, that you get a warning (normally you want to compile without warnings and errors)
and you are not in control. With control we mean, you did not decide to convert to another type, the compiler did. Also the possible loss of data could be unwanted.

Explicit conversion

The C and C++ languages have ways to give you back control. This can be done with what is called an explicit conversion. Sure you may still lose data, but you decide when to convert to another type and you don’t get any compiler warnings.

Let’s take a look at an example that uses implicit and explicit conversion:


	#include <iostream>
	using namespace std;

	int main()
	{
		int a;
		double b=2.55;

		a = b;
		cout << a << endl;

		a = (int)b;
		cout << a << endl;

		a = int(b);
		cout << a << endl;
	}

Note: the output of all cout statements is 2.

The first conversion is an implicit conversion (the compiler decides.) As explained before, the compiler should give a warning.

The second conversion is an explicit typecast, in this case the C style explicit typecast.

The third conversion is also explicit typecast, in this case the C++ style explicit typecast.

Four typecast operators

The C++ language has four typecast operators:

  • static_cast
  • reinterpret_cast
  • const_cast
  • dynamic_cast

Static_cast

Automatic conversions are common in every C++ program. You have:

  • Standard conversion. For instance: from short to int or from int to float.
  • User defined conversions (Class conversions.)
  • Conversion from derived class to base class.
    (Take a look at the inheritance tutorial)

The static_cast can be used for all these types of conversion. Take a look at an example:


	int a = 5;
	int b = 2;
	double out;

	// typecast a to double
	out = static_cast<double>(a)/b;

It may take some time to get used to the notation of the typecast statement. (The rumour goes that Bjarne Stroustrup made it difficult on purpose, to discourage the use of typecasting.) Between the angle brackets you place to which type the object should be casted. Between the parentheses you place the object that is casted.

It is not possible to use static_cast on const objects to non-const objects. For this you have to use const_cast. (Further down we take a look at const_cast.)

If an automatic conversion is valid (from enum to int for instance) then you can use static_cast to do the opposite (from int to enum.)
For instance:


	enum my_numbers { a=10, c=100, e=1000 };

	const my_numbers b = static_cast<my_numbers> (50);
	const my_numbers d = static_cast<my_numbers> (500);

Note: We add some new values (b and d). These are type-cast from int to enum.

Reinterpret_cast

The reinterpret_cast is used for casts that are not safe:

  • Between integers and pointers
  • Between pointers and pointers
  • Between function-pointers and function-pointers

For instance the typecast from an integer to a character pointer:


	char *ptr_my = reinterpret_cast<char *>(0xb0000);

Note: the example above uses a fixed memory location.

If we use the reinterpret_cast on a null-pointer then we get a null-pointer of the asked type:


	char *ptr_my = 0;
	int *ptr_my_second = reinterpret_cast<int *>(ptr_my);

The reinterpret_cast is almost as dangerous as an “old fashion” cast. The only guaranty that you get is that if you cast an object back to the original data-type (before the first cast) then the original value is also restored (of course only if the data-type was big enough to hold the value.)

The only difference with an old fashion cast is that const is respected. This means that a reinterpret_cast can not be used to cast a const object to non-const object. For instance:


	char *const MY = 0;

	// This is not valid because MY is a const!!
	int *ptr_my = reinterpret_cast<int *>( MY);

Const_cast

The only way to cast away the const properties of an object is to use const_cast. Take a look at an example:


	void a(Person* b);

	int main()
	{
		const Person *ptr_my = new Person("Joe");
		a( const_cast<Person *>(ptr_my) );
	}

The use of const_cast on an object doesn’t guarantee that the object can be used (after the const is cast away.) Because it is possible that the const-objects are put in read-only memory by the program.

The const_cast can not be used to cast to other data-types, as it is possible with the other cast functions.
Take a look at the next example:


	int a;

	const char *ptr_my = "Hello";

	a  = const_cast<int *>(ptr_my);

	a = reinterpret_cast<const char*>(ptr_my);

	a = reinterpret_cast<int *>(const_cast<char *>(ptr_my) );

Note: casting from const char * to int * isn’t very good (not to say a very dirty trick.) Normally you won’t do this.

The first statement (const_cast) will give an error, because the const_cast can’t convert the type. The second statement (reinterpret_cast) will also give an error, because the reinterpret_cast can’t cast the const away. The third statement will work (mind the note. It is a dirty trick, better not use it.)

That is all for this tutorial. In typecasting part 2 we will look at RTTI, dynamic_cast, typeid and type_info.

This entry was posted in C++ Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed. Tweet This! Tweet This! or use to share this post with others.

There are currently 6 responses to “C++ Typecasting Part 1”

Why not let us know what you think by adding your own comment!

  1. Ashish on July 24th, 2011:

    Where is link to part-2 ??

  2. admin on July 25th, 2011:

    @Ashish – I also added a link to typecasting part two in the main text.

  3. RAJI on January 8th, 2013:

    nice

  4. samba on January 22nd, 2013:

    It is cool explanation

  5. satya on June 4th, 2013:

    is it int *a or int a in last example

  6. Jack47 on September 24th, 2013:

    I have problems:

    In the last example:

    int a;

    a = reinterpret_cast(const char*)(ptr_my);
    should be :
    int* a;

    a = reinterpret_cast(char*)(ptr_my);
    If I’m wrong, please correct me.