Strong Typing
Written by Nikos Vaggalis   
Thursday, 18 November 2010
Article Index
Strong Typing
Using conversion classes
Perl
Casting
Implicit conversion
Altering representation

Casting

Now we will  turn our attention to casting and why not being  type safe can result in data loss.

Let's go to a lower level by using C and check an example of explicit conversion or casting where you use the cast operator to change the type of the value.

In C a void pointer points to something, anything. We do not have the type information of the memory contents the pointer points to; this allows the relaxed interpretation of those contents as demonstrated here.

Example 19

#include <stdio.h>
int main() {
unsigned short a;void *my_void_pointer ;
a=82;
my_void_pointer =&a;
printf("dereferenced value is : 
%c\n", *(unsigned char*) my_void_pointer);
}
//dereferenced value is :  R

A unsigned short's size is 2 bytes thus a 2 byte memory block is allocated, where value 82 will be stored.  Then we make our void pointer 'my_void_pointer' point to that value. When dereferencing the pointer (getting to the value it points at) instead of an unsigned short we use an unsigned char but surely that is not as intended!

Let's see how the value 82 maps in memory as an unsigned short:

1010010 00000000

With the instruction *(unsigned char*) my_void_pointer we intended to interpret the data pointed to as of being of unsigned char type.

Since an unsigned char is 1 byte long the data is truncated and we get 1 byte back instead of 2 which means that we get '1010010' back, instead of '1010010 00000000'

 Next we used the printf's character %c template, and it is printf' that converted the value 82 into it's ASCII representation, which is letter 'R'.

Note that unsigned char* did not turn the decimal value into its textual representation but printf's %c template did

To prove that the char type has nothing to do with textual representation, if we use the decimal template (%d) with printf, we get the decimal value back: 

printf("dereferenced value is :  
%d\n", *(unsigned char*) my_void_pointer);
//dereferenced value is :  82 

The char is just there to state the bit template and the size (8 bits) of the value, or the size of each individual element of a potential sequence stored at a memory block starting at the address the pointer points to, i.e. the elements of an array of chars.

See what happens if we altering this example a little bit:

Example 20

#include <stdio.h>
int main()
{
unsigned short d;
void *my_void_pointer;
d = 65535;
my_void_pointer = &d;
printf("dereferenced value is : 
%d\n", *(unsigned char*) my_void_pointer);
}
//dereferenced value is :  255

Here we see that the value was severely truncated, it actually lost a byte. 65535 is the capacity of an unsigned short and it's layout in memory is :

11111111 11111111

When those memory contents are interpreted as a one-byte unsigned char we lose a byte and thus the value of 255 is returned, which is equivalent  to all the bits of a single byte being turned on.

These examples have demonstrated  that when no typing is enforced we can lazily interpret the value as of any type risking data loss.

 

If you actually know the type of the value and you deliberately cast it to another type then you are on the right track, but if you don't  - or if you mistakenly cast it to another unintended type, then again you risk data loss.

This is one part of the story, the other part is the implicit conversion. 

<ASIN:1430210842>

<ASIN:0470261293>
<ASIN:0735621632>

<ASIN:0735611319>



Last Updated ( Friday, 09 November 2012 )