Open side-bar Menu
 Embedded Software
Colin Walls
Colin Walls
Colin Walls has 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, Colin is an embedded software technologist with Mentor … More »

Using an unsigned integer to store a pointer in C

 
June 17th, 2019 by Colin Walls

A common question I get is 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 ..

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

2 Responses to “Using an unsigned integer to store a pointer in C”

  1. Avatar Tim Parker says:

    Never, ever use implicit type declarations like 'unsigned var' in C – ever – it wasn't a good idea in the '70's, it isn't now. Never, ever use C compilers that allow you to use implicit types unless someone puts a gun to your head. Never, ever consider using a basic primitive type (short, int, long) to store a pointer in C or C++ unless you absolutely have to use a catastrophically ancient compiler requirements – always use a suitable sized type, e.g. uintptr_t. If you're programming asm or pushing registers, you should know the details – if you're using a high level typed language like C or C++ then code like that above should be banned, and whether an incremented pointer adds 1 or 4 or 17 a consideration that shows you're not thinking about the right issues and are probably heading towards a bug…. probably rapidly

  2. Colin Walls Colin Walls says:

    @Tim – I largely agree with you.
    Using unsigned was just me being a bit lazy.
    However, I do feel that minimizing the use of assembly language by “bending” C [carefully] is good practice.
    My point about pointers at the end was really that using them is fairly intuitive, but understanding what's going on under the hood can make the results in a debugger make more sense.

Logged in as . Log out »




© 2024 Internet Business Systems, Inc.
670 Aberdeen Way, Milpitas, CA 95035
+1 (408) 882-6554 — Contact Us, or visit our other sites:
TechJobsCafe - Technical Jobs and Resumes EDACafe - Electronic Design Automation GISCafe - Geographical Information Services  MCADCafe - Mechanical Design and Engineering ShareCG - Share Computer Graphic (CG) Animation, 3D Art and 3D Models
  Privacy PolicyAdvertise