# Multiplication or Division of pointer is not supported by C language

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

1. ### karthikbalaguruGuest

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 ?

Karthik Balaguru

karthikbalaguru, Mar 3, 2009

2. ### Richard TobinGuest

*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

3. ### Antoninus TwinkGuest

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. ### BartcGuest

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. ### Mark WoodingGuest

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. ### Keith ThompsonGuest

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

Keith Thompson, Mar 3, 2009
7. ### Keith ThompsonGuest

I hope you meant "*Not* allowed directly".
Yeah, but that's not really multiplication of pointers.
Right.

Keith Thompson, Mar 3, 2009
8. ### BartcGuest

Or rather, Not allowed.

--

Bartc, Mar 3, 2009
9. ### jameskuyperGuest

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
language.

jameskuyper, Mar 4, 2009
10. ### GuestGuest

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. ### Dik T. WinterGuest

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. ### Dik T. WinterGuest

No, at least associativity is required to make it a monoid.

Dik T. Winter, Mar 4, 2009
13. ### RichardGuest

Would you like to quote that with context please.

Or are you being typically ignorant and small minded?

Richard, Mar 4, 2009
14. ### Ben BacarisseGuest

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. ### KojakGuest

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

Sorry, :-D

Kojak, Mar 4, 2009
16. ### Richard TobinGuest

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. ### Dik T. WinterGuest

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. ### Richard TobinGuest

-- Richard

Richard Tobin, Mar 4, 2009
19. ### Nate EldredgeGuest

An affine space is pretty close.

http://en.wikipedia.org/wiki/Affine_space

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
something).

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. ### Mark WoodingGuest

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