9.6.4 Special Pointer Targets

Pointers and integers are not interchangeable. Assigning an integer constant to a pointer will generate a warning to this effect. For example:

const char * cp = 0x123; // the compiler will flag this as bad code

There is no information in the integer constant, 0x123, relating to the type or size of the destination. This code is also not portable and there is a very good chance of code failure if pointers are assigned integer addresses and dereferenced, particularly for PIC® devices that have more than one memory space.

Always take the address of a C/C++ object when assigning an address to a pointer. If there is no C/C++ object defined at the destination address, then define or declare an object at this address which can be used for this purpose. Make sure the size of the object matches the range of the memory locations that can be accessed.

For example, a checksum for 1000 memory locations starting at address 0xA0001000 is to be generated. A pointer is used to read this data. You may be tempted to write code such as:

int * cp;
cp = 0xA0001000;  // what resides at 0xA0001000???

and increment the pointer over the data. A much better solution is this:

int * cp;
int __attribute__((address(0xA0001000))) inputData [1000];
cp = &inputData;
// cp is incremented over inputData and used to read values there

In this case, the compiler can determine the size of the target and the memory space. The array size and type indicates the size of the pointer target.

Take care when comparing (subtracting) pointers. For example:

if(cp1 == cp2)
  ; take appropriate action

The ANSI C standard only allows pointer comparisons when the two pointer targets are the same object. The address may extend to one element past the end of an array.

Comparisons of pointers to integer constants are even more risky, for example:

if(cp1 == 0xA0000100)
  ; take appropriate action

A NULL pointer is the one instance where a constant value can be assigned to a pointer and this is handled correctly by the compiler. A NULL pointer is numerically equal to 0 (zero), but this is a special case imposed by the ANSI C standard. Comparisons with the macro NULL are also allowed.