Sign In
Forgot Password?
Sign In | | Create Account

Using an unsigned integer to store a pointer in C

Colin Walls

Colin Walls

Posted Dec 16, 2013
8 Comments

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 0×80000000, what is the value of pointer at the end of this code [on a 32-bit CPU]? The answer would be 0×80000004 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 0×80000001, 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.

More Blog Posts

About Colin Walls Follow on Twitter

Colin WallsI have over twenty-five 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 Visit The Colin Walls Blog

More Posts by Colin Walls

Comments 8

Post a Comment
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

horaira khan
5:54 PM Dec 17, 2013

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++; ?

Mark Garrett
12:33 PM Dec 23, 2013

Ignore that last comment I missed your initial example you did say pointer++;

Mark Garrett
2:26 PM Dec 23, 2013

"The answer would be 0c80000004 " Why 0c80000004??? Did you mean 0x80000004?

Alexei Fedorov
1:13 PM Jan 2, 2014

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).

Rahul Patel
5:26 AM Jan 3, 2014

Thanks for spotting the typo Alexei - C is next to X on the keyboard. I have fixed it now.

Colin Walls
9:47 AM Jan 6, 2014

why would some one need to go to a address like 0×80000001 ( in behalf of your example ) ?

Ahmed Eissa
12:06 PM Jan 10, 2014

Ahmed: In order to access that specific byte. I would admit that there several other ways to achieve this objective.

Colin Walls
1:48 PM Jan 10, 2014

Add Your Comment

Please complete the following information to comment or sign in.

(Your email will not be published)

Archives

Tags

 
Online Chat