Multiplication or Division of pointer is not supported by C language

Discussion in 'C Programming' started by karthikbalaguru, Mar 3, 2009.

  1. Hi,

    C states that Multiplication or Division of a pointer is not allowed .
    If they are able to support addition & subtraction, but why
    haven't they supported multiplication or division of a pointer ?
    Any difficulty in supporting those functionalities ?
    Will it be available in the future releases ?

    Thx in advans,
    Karthik Balaguru
    karthikbalaguru, Mar 3, 2009
    1. Advertisements

  2. *If* you could add two pointers, it would be hard to see why
    multiplication by an integer would not be allowed. But it's not true.
    You can't add two pointers. You can add an integer to a pointer, but
    then the analogy no longer holds.

    There are a few cases where more operations on pointers would be
    useful (e.g. it makes perfect sense to take the average of two
    pointers when doing a binary search), but they were not considered
    worth the mechanism needed to support them. Consider what the type
    of the difference of two pointers is, and then consider what the
    type of the sum would be.

    -- Richard
    Richard Tobin, Mar 3, 2009
    1. Advertisements

  3. It's surprising that Bjarn Strostroup didn't find some counter-intuitive
    and confusing interpretation of an overloaded multiplication operator on
    pointers - if he couldn't do it, who else can?...
    Antoninus Twink, Mar 3, 2009
  4. karthikbalaguru

    Bartc Guest

    Multiply and divide are available now for pointers, although you need to
    specify a base value:

    int *p, *q, *base;
    q = p * n; /* Now allowed directly */

    q = (p - base) *n + base;

    As for usefulness: if A is an int array, and base points to A[0] and p to
    any element, then this is no different to index arithmetic.
    Bartc, Mar 3, 2009
  5. karthikbalaguru

    Mark Wooding Guest

    There's a difficulty of definition. Let's start with the pointer
    arithmetic that we /can/ do:

    * we can add integers to (and subtract them from) pointers; and
    * we can subtract one pointer from another (sometimes).

    This addition fails to be associative, however:

    p + (q - r)

    is well-defined (if p, q, r are pointers, and q and r are within or
    one-past-the-end of the same object), but

    (p + q) - r

    is meaningless. Note also that there is no such thing as an additive
    inverse for pointers: although p - p = 0 for all (valid) pointers to
    objects, the notation -p is not meaningful.

    (Aside: is there a name for this kind of algebraic structure? I
    wouldn't be at all surprised if it weren't considered interesting enough
    to have a name, but it'd be nice to know for sure. ;-) )

    So, what kind of multiplication do we want? To be useful, a
    multiplication ought to be distributive over addition, and 1 ought to be
    a scalar-multiplicative identity, so

    2*p = (1 + 1)*p = 1*p + 1*p = p + p

    which is still without meaning. So that's out.

    What about multiplying two pointers? Umm, well:

    (p + 2)*q = p*q + 2*q

    but we've already decided that 2*q wasn't meaningful. So that's out.

    As for division, let's get multiplication sorted first, shall we?

    -- [mdw]
    Mark Wooding, Mar 3, 2009
  6. Only operations that make sense are supported:

    Adding an integer and a pointer, or a pointer and an integer,
    yields a pointer (the integer specifies the offset from the
    original address); this is valid only of the old and new pointer
    values point into the same object or just past the end of it.

    Subtracting a pointer from a pointer yields an integer; this is
    valid only if both pointers point into the same object or just
    past the end of it.

    Adding two pointers doesn't mean anything. Multiplying or
    dividing two pointers doesn't mean anything.

    Just because some operations exist for a type, that doesn't mean we
    should implement other operations for that type. It probably wouldn't
    be difficult to implement pointer multiplication or division in a C
    compiler; that's not the issue. The problem is that, if it were
    implemented, programmers would be able to use it -- and that would be
    A Bad Thing.
    Keith Thompson, Mar 3, 2009
  7. I hope you meant "*Not* allowed directly".
    Yeah, but that's not really multiplication of pointers.
    Keith Thompson, Mar 3, 2009
  8. karthikbalaguru

    Bartc Guest

    Or rather, Not allowed.

    Bartc, Mar 3, 2009
  9. karthikbalaguru

    jameskuyper Guest

    On systems where pointers have a simple relationship to addresses in a
    linear address space, you can probably get exactly what you're looking
    for just by converting the pointers to intptr_t before carrying out
    the mathematical operations. It's not portable, but neither is the
    concept that you're trying to get implemented.

    In the more general case, addition, multiplication, and division of
    two pointers is a meaningless concept. Addition or subtraction of an
    integer to a pointer already has a well defined meaning; most other
    operations between pointers and integers are manifestly meaningless.

    However, there's one operation that might usefully supported: pointer
    % integer:

    char c[2*sizeof(short)];
    char *pointer = c+sizeof(short);

    ptrdiff_t remainder = pointer % align_of(short);
    pointer -= remainder;
    short *ps = (short*)pointer;

    The result of the % operation would be such that the code given above
    would result in ps containing a value that points at a location
    correctly aligned to store a 'short'. Such a feature would be pretty
    much useless without an align_of() operator also being added to the
    jameskuyper, Mar 4, 2009
  10. karthikbalaguru

    Guest Guest

    But, but, but.. Richard-I-single-step-all-my-code says that pointers
    are addresses are integers and you multiply integers so you *must* be
    able to multiply pointers!

    This utility function may be handy

    /* multiply two addresses together */
    void *addresses_product (void *a1, void *a2)
    /* use long to hold the 32-bit address */
    return (void*)((long)a1 * (long)a2);
    Guest, Mar 4, 2009
  11. p1 + (p2 - p1)/2

    On the other hand, naive adding two pointers and dividing by 2 would not
    result in a valid pointer on some machines.
    Dik T. Winter, Mar 4, 2009
  12. No, at least associativity is required to make it a monoid.
    Dik T. Winter, Mar 4, 2009
  13. karthikbalaguru

    Richard Guest

    Would you like to quote that with context please.

    Or are you being typically ignorant and small minded?
    Richard, Mar 4, 2009
  14. and a monoid is closed under its (single) operation. Here we have two
    sets and two related operations (-: P -> P -> Z and a commutative +: P
    -> Z -> P). I bet it has a name in category theory -- everything else
    seems to have a name in category theory.
    Ben Bacarisse, Mar 4, 2009
  15. karthikbalaguru

    Kojak Guest

    Le Wed, 04 Mar 2009 12:42:30 +0000,
    Ben Bacarisse a écrit :
    Say, a "pointoid".

    Sorry, :-D
    Kojak, Mar 4, 2009
  16. Of course I know you can do it like that, which is why I said that
    those operations were not considered worth the mechanism needed to
    support them. I was just pointing out that the operations are
    not meaningless or even useless.
    It would require some shifting or masking, just as the subtraction in
    your expression above can't be done naively.

    -- Richard
    Richard Tobin, Mar 4, 2009
  17. Suppose a system with the data address space starting at 0x80000000.
    Assume p1 and p2 to be char pointers. In that case the first can be
    implemented naively while the second can not.
    Dik T. Winter, Mar 4, 2009
  18. True, I hadn't considered overflow.

    -- Richard
    Richard Tobin, Mar 4, 2009
  19. An affine space is pretty close.

    In our case, I guess we should replace the vector space V in the
    definition by a ring (the integers, or the integers mod (size_t)-1 or

    A simple example of an affine space in geometry is a plane in R^3 not
    passing through the origin.
    Nate Eldredge, Mar 4, 2009
  20. karthikbalaguru

    Mark Wooding Guest

    Quibble: p - q is short for (p_offset - q_offset) if they have a common
    base. The result is an integer, not another pointer. (Probably a
    braino, but worth pointing out.)
    Indeed. Your explanation was much clearer than mine: thanks.

    -- [mdw]
    Mark Wooding, Mar 4, 2009
    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.