Pointers and References – Part 3 (Kinky Stuff)

Once in a while, I show my students some fancy examples of what you can (but shouldn’t) do with pointers. Most students would be watching the screen with baffled looks on their faces. Those who cannot find any interest in such experiments should seriously consider changing their subject of study, because they do not have the necessary intrinsic motivation to become a ruler of the binary world. ๐Ÿ˜‰

Here are two easy-to-understand examples in C code.

A brief note for fellow teachers and college professors: Of course there are much more tricks you can do. Once you have deep background knowledge about CPUs and storage management, you’ll have an inexhaustible magic hat that allows you to instantly “pull out” any trick during a lecture. Avoid showing such tricks in classes with a high number of less motivated students. In such classes it might be more fun joining your students to a nearby pub instead. ๐Ÿ˜‰

1. Magic Numbers

Question: What is the output of the following program?

#include <stdio.h>

int main() {

ย  int a = 1919184449;
  int b = 1632444517;
  int c = 175269225;
ย  int var1 = 1801808965, var2 = 1852797556;
ย  int var3 = 1668508521, var4 = 1701606760;
ย  int var5 = 1952797728, var6 = 1851879028;
ย  int var7 = 2663;
ย  printf( "%s", &a );
ย  return 0;

}

Answer:

Andre Maier
Elektronikschule Tettnang

So why’s that? Simply because of four factors playing together.

  • An array of characters (variable a) is a pointer. It points to the start of a character sequence stored in your computer’s memory. Here the only character of the sequence is ‘H’ … which for some strange reason doesn’t seem to have anything to do with the output.
  • The format specifier %s used in the printf-statement retrieves characters from your computer’s memory beginning from the address of the pointer variable provided (a). %s won’t stop retrieving characters before it reaches an “End of Text” character (ASCII value 0). This is why strings in C always need to be terminated by an ASCII zero.
  • Any variable declared in a program will be placed somewhere in your computer’s memory. Depending on the architecture of your computer, subsequent variables may be placed directly before or after antecedent variables.
  • Any integer value causes a specific bit pattern in the memory. Depending on the architecture of your CPU bytes may be switched (depending on whether you are running the program on a “little endian” or a “bit endian” CPU).

Got the trick?

What I did is that I just choose int values which cause exactly the pit pattern of the ASCII values of the text I want to display. Because of my processor’s architecture (Intel/AMD) I needed to swap the bytes … you won’t need this step if you run the program on Motorola architecture. The char array a just serves as a staring point for %s. The ASCII zero value (binary 0000 0000, 1 byte) is hidden in the bit pattern of woo.

Well, it is obvious why you should never write such programs in real life: Just try to delete a certain letter from the text, for example. ๐Ÿ˜‰

2. Cast the Impossible

You probably know how a type cast is working. For example, if you assign the value 1.678 to an integer variable i, your computer will just truncate all decimal places (so the result is i = 1). Some programming languages, such as Java, will probably warn you against some “loss of precision” and/or require explicit type casting. It is obvious that this is the most useful way to handle such casts.

What happens behind the curtain is that the representation of the value changes from IEEE754 format to the “usual” base 2 integer representation. The IEEE754 format is used for representing floating point numbers. Mathematically spoken, IEEE754 is a base 2 exponential representation that consists of a signum, a mantissa and an exponent. (I guess I’ll cover this in one of my future postings.)

The change of representation happens automatically. It happens every time when you assign a float value to an integer variable.

We could now raise the following questions:

Is there a way to assign the IEEE754 bit pattern directly to an integer variable without changing its representation in memory? Can we bypass the well-intentioned change of representation?

(If your answer is: Who would want to do this anyway? … Stop reading and get your hands off your poor computer!)

The answer is: YES! We can! ๐Ÿ˜‰

Let’s take a look at the following program.

#include <stdio.h>

int main() {

   float f = 0.1;
   int* int_ptr = (int*) &f;
   int int_value = *int_ptr;
   printf( "%x\n", int_value );

}

The output of the program is 3dcccccd, which is the IEEE754 representation of the floating point number 0.1.

Here is how it works: In the second line of code inside function main() we declare a pointer to int and assign to it the address of the float variable f. The compiler would (of course) notice that we are going to mess up our program, because the address of f is pointing to a float variable instead of pointing to an int variable. That’s why we need to “cheat” by explicitly casting the float address to an int pointer. It’s like telling the compiler “I know, I know … but I really intended to do this”.

If we now access the content of the memory where the int pointer is pointing to … voilรก! We directly access the bit pattern of the floating point number while your computer “thinks” it is “looking” at an integer number.

Oh, for those of you who are sure I wouldn’t be able to create any related assignments: Have you ever tried to apply bit twiddling operations, e.g. bitwise &, on a floating point number? I know several practical applications of this technique which could easily be used for nice assignments! HARHARHARRR! ๐Ÿ˜‰

What you could see here is that pointers allow you to cast everything into anything you want it to be — even if it doesn’t seem to make sense. If you like you can have your computer interpreting the memory address of a function as a IEEE754 floating point number — which really wouldn’t make any sense, I guess.

That’s all for now, folks. While writing this posting a large number of new topics and ideas for further postings (mostly computer basics) crossed my mind. Let’s see what comes up next.

Have a great time!

— Andre M. Maier

Advertisements

About bitjunkie

Teacher, Lecturer, and BITJUNKIE ...
This entry was posted in Pointers, Uncategorized and tagged , , , . Bookmark the permalink.