Comparing pointers

Discussion in 'C Programming' started by J Caesar, Jun 5, 2007.

  1. J Caesar

    J Caesar Guest

    In C you can compare two pointers, p<q, as long as they come from the
    same array or the same malloc()ated block. Otherwise you can't.

    What I'd like to do is write a function
    int comparable(void *p, void *q)
    that will take any two pointers and decide whether they can be compared
    or not.

    I really can't think how to do this - any suggestions?

    J Caesar, Jun 5, 2007
    1. Advertisements

  2. Really!? How have I managed to do so all these years?

    Pointers are just addresses - usually 32-, these days more and
    more, 64-bit unsigned integers. Which you can always compare at will.
    Usually you'll want for them to be pointers to the same type of data, of
    Ivar Rosquist, Jun 5, 2007
    1. Advertisements

  3. It can't be done. Or rather, it can't be done portably. To do it
    non-portably is probably either trivial or the compiler has no issues with
    pointers to different blocks.

    The "no comparison" rule is a kludge to allow for funny architectures. It
    becomes a nuisance when you need to know whether a pointer comes from a
    certain block or not. However you don't need that information very
    frequently, and on balance it is probably better to make the compiler easier
    to implement or code to run faster.
    Malcolm McLean, Jun 5, 2007
  4. You're right, you can't. But why do you want to? What are you trying
    to achieve?

    Note that you can compare pointers for equality even if they are
    from different objects.

    -- Richard
    Richard Tobin, Jun 5, 2007
  5. It is undefined behaviour. Realistically a flat memory architecture is just
    going to do a starightforwards subtraction of bits. However it could trap or
    return funny results on some machines.
    Malcolm McLean, Jun 5, 2007
  6. J Caesar

    Flash Gordon Guest

    J Caesar wrote, On 05/06/07 22:44:
    Your initial thought is correct, you can't do the check in standard C.
    Flash Gordon, Jun 5, 2007
  7. Pointers are not necessarily just addresses: pointers may be opaque
    with storage silently managed "under the hood", or pointers may
    include type information, or pointers may include not have the
    address information in numeric order (e.g., Cray put the character
    offset bits in the upper byte). Or, as was common on VMS, pointers
    might be the address of "descriptors" -- a block of data that
    describes the type and array and virtual memory address of the
    actual storage. And when you are working with a Harvard architecture,
    a pointer to a function could have exactly the same numeric value
    as a pointer to an object: since C does not provide any operations
    that translate between function pointers and object pointers, there
    is no conflict in having a function pointer with the same value
    as an object pointer, with the code knowing which kind of instructions
    are needed for the correct kind of access.
    Walter Roberson, Jun 5, 2007
  8. J Caesar

    J Caesar Guest

    This gives one method: write a wrapper to malloc to store a pointer to
    each block allocated together with the size of the block. Then do an
    exhaustive search over all pointers to all elements of all blocks
    allocated to find which blocks p and q are in (only needs you to compare
    each pointer for equality with p or q, which is legal). And you're done.

    I see two problems: 1) very inefficient if large tracts of memory are
    allocated; 2) fails if p or q point inside statically allocated arrays
    rather than malloc()ed blocks.

    J Caesar, Jun 5, 2007
  9. [/QUOTE]
    Which shows poor judgment but good taste.

    -- Richard
    Richard Tobin, Jun 5, 2007
  10. By ignoring the C Standard and by avoiding any C implementations with
    segmented memory.
    christian.bau, Jun 5, 2007
  11. I don't believe there's any way to do this in standard C. Attempting
    to compare the pointers invokes undefined behavior; there's no way to
    detect that before running into it.
    Keith Thompson, Jun 6, 2007
  12. J Caesar

    Ian Collins Guest

    Segmented or virtual memory.
    Ian Collins, Jun 6, 2007
  13. J Caesar

    Vinoj Guest

    Typecast the pointers to 'unsigned int' before comparing them.

    Thanks, Regards,
    Vinoj, Jun 6, 2007
  14. J Caesar

    Ian Collins Guest

    Cast, not typecast. This is bad advice for at least three reasons:

    Appropriate pointers can be compared without any casts.

    On many systems, including the one I'm typing this on, pointers are
    larger than unsigned int.

    Casting hides the intent.
    Ian Collins, Jun 6, 2007
  15. J Caesar

    Vinoj Guest

    I am yet to buy a 64-bit system. Due to the lack of OS support I am
    unable to buy one. I just want to run Linux on a 64-bit system. Can
    you please provide me a pointer, where I can readily get IA-64 Linux
    Distributable. It seems there is no support for DOS in 64 bit OS, so
    I cannot get a DOS box on Windows if I have a Dual Boot? I just dont
    want to go for a expensive server models that take up my room space
    where I already I have 2 machines one Pentium 4 HT and one Celeron,
    for device driver WinDBG and such stuff.

    Thanks, Regards,
    Vinoj, Jun 6, 2007
  16. Vinoj said:
    Presuming you mean "cast", how would that help to establish whether they
    can be compared /without/ the cast? And if your purpose is to avoid the
    question altogether by making sure they can *always* be compared,
    consider the possibility that the cast loses information - for example,
    imagine a system with 16-bit unsigned ints and 20-bit pointers. (No,
    that wasn't an accidental choice.)
    Richard Heathfield, Jun 6, 2007
  17. J Caesar

    pete Guest

    #4 The result of the comparison of the resulting 'unsigned int'
    values, doesn't imply which pointer has the higher address.
    pete, Jun 6, 2007
  18. Your question has nothing to do with C, or even with this discussion.
    Try a Linux-specific newsgroup.
    Keith Thompson, Jun 6, 2007
  19. p or q may be interior pointers to a malloc'd block.

    Just comparing them for equality with the base address won't work.
    You need to compare base <= p < (base+size), at which point you're
    back to undefined behavior if p is not a pointer into the block.

    There isn't any way to do it portably unless you control allocation.
    If you use your own heap functions and arrange that all allocations
    are made from an array under your control, then you can safely compare
    any pointers into those blocks.

    But it still won't help in the general case. Technically, by the
    standard, comparing unrelated pointers in any way (even for equality)
    produces undefined behavior. The exception is that any pointer may be
    compared against the constant NULL ... but then the value of NULL is
    implementation defined and _not_ guaranteed to be zero.

    People have been writing technically non-portable pointer code since
    the beginning. Most have just been lucky that the platforms they
    targeted had memory layouts which coincidentally corresponded to the
    definition of a C array and pointers were simple addresses. As Walter
    Roberson mentioned earlier, there are systems in which the notion of a
    pointer is more complicated. There are even some systems in which
    memory is not organized as an array.

    George Neuner, Jun 6, 2007
  20. J Caesar

    Clark Cox Guest

    No, comparing for equality is specifically allowed by the standard.
    Clark Cox, Jun 6, 2007
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.