RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


There's More to Typecasting than C++ Cast Operators : Page 3

Knowing exactly which typecasting operation is required for a given task and familiarity with the little known techniques that automate type conversions is essential--even in state-of-the-art C++ projects.


Broad Cast
In applications that transmit data over networks or use persistent objects, casting an object to a char array and vice versa are common operations. Using reinterpret_castor C-style cast for every such conversion is tedious and messy. The infamous "union hack", in spite of its bad reputation, can simplify this task by eliminating explicit cast expressions from your code.

Suppose you have a networking application that receives a variable of type double from a remote client. The variable is received as stream of bytes. Your task is to convert that char array to double, print its value and then store the value in a file. In other words, you need to cast a char array to double and then cast the result back to a char array. The easiest way to do that is to define a union that contains two members; the first member is of type double and the second one is an array of sizeof(double)char:

#include <fstream>
using namespace std;

union hack 
//both members overlap exactly  
 double d;
 char bytes[sizeof(double)];
} h;

char * getbytes(size_t sz); //reads client data
h.d= *(double*) getbytes(sizeof(double));
cout<<"received the value: "<<h.d<<endl;
ofstream archive("values.dat", ios::binary);
archive.write(h.bytes, sizeof (h.d));

To reconstitute the original double value from the file values.dat, use the union like this:

ifstream archive("values.dat");
archive.read(h.bytes, sizeof (h.d));
cout<<"retrieved value: "<<h.d<<endl;

In simpler words, the union allows you to view the same piece of memory either as a double or as a char array simply by switching between the two union members. Recall that all union members have the same address. To ensure that they also occupy exactly the same number of bytes, calculate the size of the char array using sizeof(type_of_first_member). The union hack eliminates the drudgery of using reinterpret_castin every I/O operation. Notice that the code doesn't use a single cast expression.

Obviously, the next evolutionary step is to replace the union with a union template, thus automating the conversion from an arbitrary type Tto a char array:

template <typename T> union hack                
  T data;
  char bytes[sizeof(T)] ;

Dare to Be Different
Bad PR and snobbery shouldn't deter you from using features that get the job done quickly, elegantly and often with less bugs and hesitation as witnessed with C++ cast operators. C-style cast has three advantages over C++ style cast:

    • It's less verbose.

  • It frees you from the confusion between static_cast and reinterpret_cast.

  • It can perform two cast operations in a single expression.

The union hack eliminates the clutter and inelegance of recurrent cast expressions.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date