Suppose I have the global variables:

char *min_ptr, *max_ptr;

and the function:

void f(int *p)
{
    if(min_ptr > p)
        min_ptr = p;
    if(max_ptr < p)
        max_ptr = p;
}

If C does not guarantee that addresses are stored the same way as unsigned long, I guess I can't initialize my variables as follows:

char *min_ptr = ULONG_MAX, *max_ptr = 0;

How can I initialize min_ptr and max_ptr to the smallest and largest addresses respectively? And is it even valid to use the <, >, <=, or >= operators with pointers?

有帮助吗?

解决方案 3

0 is not a valid address, that's why it's used to represent the null pointer constant. So you can just do:

char * min_ptr = NULL;
char * max_ptr = NULL;

/*  Other stuff  */

void f(int *p) {
    if( min_ptr == NULL || min_ptr > p )
        min_ptr = p;
    if( max_ptr == NULL || max_ptr < p )
        max_ptr = p;
}

without messing about with that other stuff.

其他提示

Pointer subtraction or pointer comparison using <, <=, >, or >= has undefined behavior unless both pointers point to elements of the same array object, or just past the end of it. (For this purpose, a single object is treated as a single-element array.) The relational operators compare the array indices, and subtraction yields the difference in elements (&arr[5] - &arr[2] == 3, for example).

It's likely to "work" (i.e., give you more or less consistent results) on most systems, though subtraction may still give nonsensical results if there are alignment problems.

You can convert any pointer-to-object value to intptr_t or uintptr_t (defined in <stdint.h>) and back again without loss of information. Since intptr_t and uintptr_t are integer types, subtractions and comparisons on them are well defined -- but that doesn't mean that the comparison means anything with respect to the pointer values. And of course subtraction can overflow.

You can either live with the fact that your code's behavior is not defined by the standard (though it may happen to work on your system), or you can find a different way to solve your problem. For the latter, we might be able to help if you'll tell us what problem you're trying to solve.

The comparison operators are valid to use.

For the limits, use

INTPTR_MIN
INTPTR_MAX

from stdint.h.

And, FYI, I believe there is a better way to do what you are trying to do.

The header file <stdint.h> in C99 has some useful things defined. uintptr_t is a normal integer type that can contain a pointer. stdint.h defines Maximum and Minimum on all it's types.

So this should work

void *ptr_max = UINTPTR_MAX;

UINTPTR_MIN is not defined as pointer's are unsigned their smallest value is always 0.

Yes you can compare pointers. It's useful in array stuff. Eg checking a array based ring buffer is not full:

// This code has some bugs. Eg, it does not handle wrap arround.
if (ring_buff_back + 1 < ring_buff_front) {...

Note the subtraction on pointers return a ptrdiff_t which is similar to intptr_t.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top