Casting operators and the (type *) casting operator

• Casting operators

• Use of casting operators

 A casting operator tells the compiler to apply the indicated type conversion to the values The type conversion often entails changing the encoding method used to represent the value

• Example:

 ``` Value int (2's complement) encoding ------------------------------------------------------ .. (1) 00000000 00000000 00000000 00000001 Value IEEE 754 (float) encoding ------------------------------------------------------ .. (1) 01111111 10000000 00000000 00000000 ```

• That means:

 ``` int a; a = 2; // will store 00000000 00000000 00000000 00000010 in a float b; b = a; // will store 01000000 00000000 00000000 00000000 in b // (The red portion is the mantissa in excess 127 code) // This is the representation of 2.0 in float (IEEE 754 code) ```

• Casting of reference typed variables

• Facts:

• A reference type stores an address:

 ``` int *a; // a stores an address of an int typed variable float *b; // b stores an address of an float typed variable ```

• An address is an unsigned integer

Therefore:

 ``` The encoding method used for values stored in a is: Binary number system The encoding method used for values stored in b is: Binary number system ```

• Conclusion:

 There is no conversion of values necessary for any reference data types !!! (Because a reference is an address and address are all unsigned integers)

• Casting operators for reference data types

• Syntax:

 ``` Type1 *p; Type2 *q; p = (Type1 *) q; ```

meaning:

 Convert the reference value to a Type 2 variable stored in the variable q into a reference value to a Type 1 variable And then store the result in the variable p

• As you have seen above, there is no change in encoding necessary.

Effect of p = (Type1 *) q is:

 Store the address in variable q into the variable p

• Dangerous use reference variables

• Fact:

 C is a very dangerous (= powerful) programming language The reference data type allows to programmer to access any memory location

• Example:

 ``` int main(int argc, char *argv[]) { int i = 1234; int *p; /* ===================================================== Read the memory location 4000 ===================================================== */ p = (int *) 4000; // Give p the value 4000 printf("Value stored at memory location 4000 = %d\n", *p); } ```

• Note:

 Due to memory protection (the part of the memory that contains instructions is protected from read operations), a read operation can cause a crash

• Demo:

 ``` setarch \$(uname -m) -R /bin/bash cd ~/demo/c/set2 gcc peek-mem1.c a.out ```

• Trick to copy variables of different types without type conversion

• Recall:

• When a value is assigned to a variable of a different data type, the C compiler will always perform a conversion of the data representation

Example:

 ``` int a; float b; b = 2.0 // IEEE 754 repr for 2.0 is: // 01000000000000000000000000000000 a = b; // C will perform conversion: // IEEE 754 repr ===> 2's complement repr // Stores 00000000000000000000000000000010 in a ```

• Trick to skip the conversion operation:

 ``` int a; float b; int *p; p = (int *) &b; // Make C think that p points to an int variable // Note: &b is (float *) !!! a = *p; // int = int !!! // C will not perform conversion ! ```

Example:

 ``` int a, *p; float b, *q; b = 2.0; // b = 01000000000000000000000000000000 !!! a = b; // C detects type change: performs type conversion to int ! printf("a = %d, b = %f\n", a, b); // Conversion took place (implicitly) /* =========================================== How to circumvent C's implicit conversion =========================================== */ p = (int *)&b; // Make p point to b a = *p; // Read b as an int typed variable ! printf("a = %d, b = %f\n", a, b); // NO conversion ! ```

Output:

 ``` a = 2, b = 2.000000 a = 1073741824, b = 2.000000 The bits in a = 01000000000000000000000000000000 Interpreted as an int, the value is: 230 = 1073741824 ```

• Example Program: (Demo above code)

How to run the program:

 Right click on link and save in a scratch directory To compile:   gcc casting1.c To run:          a.out