Sunday, July 31, 2011

C Gotcha Of The Day: Pointers aren't integers

The C standard is clear that pointers are not required to be convertible to or from an integer.

Section 6.3.2.3.5-6 in the C99 draft

An integer may be converted to any pointer type. The result is implementation-defined, might not be properly aligned, and might not point to an entity of the referenced type.)

Any pointer type may be converted to an integer type; the result is implementation-deļ¬ned. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

Basically, you can't depend on the following code doing anything useful:

int *p = (int*)0xff;

The C standard does not define a machine with a flat memory model. Old Intel systems are an example of a non flat memory model, they had a segmented memory model where a pointer needed a segment and offset.

Conversion to a string is also implementation defined in C, from 7.19.6.1 fprintf, the section on the %p format specifier:

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printable characters, in an implementation-defined manner.

And from fscanf:

Matches an implementation-defined set of sequences, which should be the same as the set of sequences that may be produced by the %p conversion of the fprintf function. The corresponding argument shall be a pointer to a pointer to void. The interpretation of the input item is implementation-defined. If the input item is a value converted earlier during the same program execution, the pointer that results shall compare equal to that value; otherwise the behavior of the %p conversion is undefined.

It does appear that even though the result of %p is implementation defined, it is guaranteed that you can fprintf and fscanf pointers and get back the same result inside the same program execution.

No comments:

Post a Comment