Thought Leadership

Using an unsigned integer to store a pointer in C

Nowadays, social networking is becoming quite “grown up” and goes a long way beyond teens discussing how to (mis)spend their time or posting 200 near identical and blurred photographs of last night’s awesome [sic] party. Although I do use Facebook, in a professional context I think that LinkedIn has much more value. Although it is essentially “Facebook for adults”, there is true potential for building a strong professional network, if you work in company or industry with global reach.

I particularly like some of the LinkedIn groups and I have recently been participating in a discussion about embedded C programming

This particular discussion topic is all about the use of pointers in C and whether it is OK to store the value of a pointer [i.e. an address] in an “ordinary” variable – like an unsigned integer. The specific example was in an embedded application – specifically in driver code. A simple way to express the idea in question is like this:

unsigned normal;
unsigned *pointer;

 

pointer = &normal;
normal = (unsigned)pointer;

This would result in the variable normal containing its own address. I will consider shortly whether this code would actually work or not.

In broad terms, most of the time, code should:

  1. perform the required function
  2. be readable/maintainable
  3. be readily portable to a different CPU

#3 may be considered less important in certain instances – like device drivers in embedded systems..

For most, but not all, modern CPUs, an address is the same bit size as a word of memory; i.e. most 32-bit CPUs have 32-bit address space as well as favoring operations on 32-bit data. In this context, most, but again not quite all, CPUs allow addresses to be stored in memory locations and registers and be operated on like any other data. Hence, the code above would be likely to work. Whether it is a good idea to write it is another matter.

To an assembly language programmer, manipulating addresses in this way is an everyday occurrence. It is the responsibility of the programmer to keep track of what is an address, what is an address of an address and what is data etc. There are also some high level languages – untyped languages – that operate in the same way; Forth and BCPL are examples that come to mind.

The majority of high level languages support data typing to a lesser or greater extent. This means, in effect, that the programmer specifies that a variable contains data or contains an address and the language only allows appropriate operations on that variable.

A possible area of confusion is between pointers and addresses. They are not one and the same thing. A pointer contains an address, for sure, but it also intrinsically knows about the kind of data that is stored at that address, which makes pointer arithmetic work correctly, but may be confusing to the newcomer. For example:

unsigned array[3];
unsigned *pointer;

 

pointer = array;
pointer++;

The incrementing of the pointer could also be written:

pointer += 1;

or

pointer = pointer + 1;

If array is at memory location 0x80000000, what is the value of pointer at the end of this code [on a 32-bit CPU]? The answer would be 0x80000004 because the compiler knows that the pointer needs to be moved 4 bytes at a time to move to the next array element. If you actually wanted to point to 0x80000001, you might need to write code like I started out with.

So, it all comes down to whether you want to work with a pointer or an address. Most of the time, a pointer does exactly what you want. However, there are special circumstances when you want to take an “assembly language” view in C code and this approach may be acceptable. But, I emphasize that this is only in special circumstances like a driver or maybe a debug monitor. Otherwise, such code is very unwise indeed.

Colin Walls

I have over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Learn more about Colin, including his go-to karaoke song and the best parts of being British: http://go.mentor.com/3_acv

More from this author

Comments

0 thoughts about “Using an unsigned integer to store a pointer in C
  • Recently I have faced same situation, forced to use variable for storing the address, was in dilemma , thanks for clearing it out.
    I have to use memory address contained in linker symbol in my application code for that I have used this

  • I’m kind of surprised that you don’t bother with int in declarations i.e. unsigned int normal;
    I assume thats economy of typing but then suggest all of the long forms of adding 1 and skip pointer++; ?

  • Right, the next address using pointer++ or pointer += 1 would be 0x80000004. Hence if you want to work with individual byte or bits of 32-bit data that you store in memory, then you have to go with the assignment of pointer to unsigned int. This also is better approach then taking the 32-bit number and storing it in some temporary variable and then rotation, as this might be more complex and also may consume more memory (if memory is the constrained as in most OS based embedded system).

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.sw.siemens.com/embedded-software/2013/12/16/using-an-unsigned-integer-to-store-a-pointer-in-c/