473,903 Members | 4,060 Online

Why multiplication not allowed?

Hi,

Why multiplication of pointers is not allowed?
Till now I only know this, but not the reason why!

PS: As a rule, I searched the FAQ, but could not

--
Vijay Kumar R Zanvar
Nov 14 '05
87 11276
Flash Gordon wrote:

It's not holding your hand, it's just not providing something that makes
no sense. You can always side-step the limitation by casting the
pointers to long long and multiplying them, although there is no
guarantee that they will actually fit in to a long long.

FYI, there is a guarantee in C99 that an object pointer will fit in a
intptr_t, if that type is provided.

-Kevin
--
My email address is valid, but changes periodically.
Nov 14 '05 #31

On Wed, 7 Jan 2004, Kevin Goodsell wrote:

August Derleth wrote:
Kevin Goodsell wrote:

The question Ben is asking is, what would you propose pointer
multiplication do? How would you define the operation? I can't think
of any way in which multiplying a pointer by any other value would be
useful or even meaningful.
The way I reason is like this: If I take i and assign an address to it
(that is, I make it a pointer), i is the name of a block of memory that
holds a certain string of bits or trits or decimal digits that compose
that address. At this layer of abstraction, it's no different from an
int or a float. Since I can multiply two ints and stand a good chance at
getting a meaningful result, why not two pointers? Or an int and a pointer?

Because the result is *not* meaningful for pointers.

Moreover, the *operation* is not [yet] meaningful for pointers.
When August says that he can "multiply" two integers, that means: treat
the bits as a positional notation with this bit equal to 1, this bit
equal to 8, etc., and carry out multiplication in the grade-school
longhand format. When August says he can "multiply" two floats, that
means: treat this set of bits as one positional number, this set of
bits as an exponent, add a 1 to the front, add the exponents, carry
out longhand multiplication on the other bits, and store the result back
in the old format.
These are two *very* *different* operations at the machine level.
Yet at the "conceptual " level, they go by the same name.
August proposes to make a new operation on pointers, also going by
the name "multiplication ," but he hasn't told us the machine-level
meaning of the new operation. What is the computer supposed to *do*
with these bits?

Your question is somewhat like asking "why can't I assign to a
function?" or "why can't I take the square root of a struct?" There's
just no logical reason why you *should* be able to.

My response to this is that the compiler shouldn't hold my hand that
much.

I'd say the compiler wasn't holding your hand at all. Maybe some
languages go to the effort of setting up a framework in which it is
possible to "multiply" pointers. C doesn't bother. If you want to
assign semantics to the expression 'p*q', you can jolly well do it
yourself, says C.

<snip> All I can say to this is that I'm glad you didn't design C.

You might also be interested in BCPL. I know almost nothing about it,
but I believe I read that it only had 1 type: the machine word. I
imagine this would give you the kind of complete freedom from
hand-holding that you seem to want. (It's also possible that the
language I'm thinking of is B, not BCPL.)

Both. BCPL came before B, but B didn't add any type-checking to the
root language as far as I know.

<Blatant plug> You can multiply "pointers" in Day-9, too; it's actually
much more similar to the BCPL described here
http://www.lysator.liu.se/c/msb-on-b.html
than I'd previously realized. I like the idea of floating-point
operators, too...
http://www.geocities.com/arthur_odwyer/day9/
</plug>

-Arthur
Nov 14 '05 #32
Kevin Goodsell wrote:

[...]
The question Ben is asking is, what would you propose pointer
multiplication do? How would you define the operation? I can't think
of any way in which multiplying a pointer by any other value would
be useful or even meaningful.

The way I reason is like this: If I take i and assign an address to it
(that is, I make it a pointer), i is the name of a block of memory
that holds a certain string of bits or trits or decimal digits that
compose that address. At this layer of abstraction, it's no different
from an int or a float. Since I can multiply two ints and stand a good
chance at getting a meaningful result, why not two pointers? Or an int
and a pointer?

Because you *can't* multiply two pointers, or an int and a pointer,
and stand a chance at getting a meaningful result.

Pointers are not integers. Pointer arithmetic in C is not defined in
terms of treating the bit patterns composing the pointer values as
integers and performing integer arithmetic on them; it's defined in
terms of what object the resulting pointer value points to.

For example, if p is a pointer, the machine-level operations that are
performed to evaluate the expression (p + 4) depend on the type of p.
If p is a char*, (p + 4) points to a location 4 bytes "after" the
location pointed to by p; if p is an int*, (p + 4) points
4*sizeof(int) bytes "after" the location pointed to by p. If p is a
void*, the expression (p + 4) is illegal (though some compilers may
support it as a language extension (unwisely, IMHO)).

Another example: On Cray vector machines, a machine address points to
a 64-bit word. The C compiler implements 8-bit chars (CHAR_BIT == 8)
by "cheating" a little. (I put the word "cheating" in quotation marks
because what the C compiler does is perfectly legitimate; it just
doesn't map directly to the underlying hardware.) A char* is
implemented as a word address with a byte offset kludged into the
high-order 3 bits. (I actually don't know how much hardware support
there is for this format.) Multiplying two such pointers makes as
much sense as taking the square root of a struct.

If, for some reason, you want to treat the contents of two pointers as
if they were integers, multiply them, and store the resuting integer
bit pattern into a pointer, you can do so. I don't think a cast from
a pointer to an integer of the appropriate size, or vice versa, is
guaranteed to just copy the bits, but it probably does so on most or
all implementations . If you're concerned about that, you can use
memcpy(), which is guaranteed to copy the bits. Using explicit
conversions, you can multiply two pointers (treating the pointers' bit
patterns as integers and treating the resulting integer bit pattern as
a pointer) as easily as you can take the square root of a struct
(treating the struct's bit pattern as a double). The compiler won't
hold your hand while you do this, but it won't stop you. Of course,
you'll invoke undefined behavior, and I can't think of any possible
use for the result.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #33
Joona I Palaste <pa*****@cc.hel sinki.fi> writes:
Sean Kenwrick <sk*******@hotm ail.com> scribbled the following:
But I think the reason I didn't get the job was because one of the other
questions the interviewer asked me was to tell him what was wrong with the
following statement:

i=+i;

I said that there was nothing wrong with it, but the interviewer claimed
that it was an ambiguous statement because it could mean adding i to itselt
or setting i to +i. I got into an argument with him saying that he must
be confused with i+=i; but he was adament he was right and got annoyed that
I was disagreeing wih him.

Afterwards I wondered whether this might have been some kind of syntax left
over from a very early incarnation of C which was subsequently dropped.
think that this guy was just a complete idiot.

Yes, this is an obsolete feature of C. =+ and =- originally meant the
same as += and -=. Whoever designed them that way must have been
drinking something really strong. AFAIK they were dropped when ISO
standardised C.
That the interviewer still clung to the obsolete meanings of those
operators makes me feel that he wasn't the proper person to interview

The =+ syntax was dropped long before ISO C; it had vanished by the
time K&R1 was published.

Not many years ago, I used a compiler (VAXC, I think) that allowed the
old =+ syntax, but I think it at least issued a warning about it. (It
also helpfully "corrected" the unrecognized "signed" keyword to
"unsigned". ) The oldest C compiler I now have access to (circa 1988)
just treats =+ as a syntax error.

What's really wrong with the statement is that it lacks whitespace and
doesn't do anything useful.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #34
Keith Thompson <ks***@mib.or g> spoke thus:
Because you *can't* multiply two pointers, or an int and a pointer,
and stand a chance at getting a meaningful result.

True enough. But let me suggest something, assuming I don't make a
mistake in my reasoning before doing so.

If p is a pointer pointing to a memory region of sufficient size,

(p+5)==(p+5*siz eof(*p))

right? Likewise for p-5. Then (I suggest),

(p*5)==(5*sizeo f(*p))

would be sensible. Not needed, but meaningful, yes?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cybers pace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #35
Christopher Benson-Manica wrote:
Keith Thompson <ks***@mib.or g> spoke thus:
Because you *can't* multiply two pointers, or an int and a pointer,
and stand a chance at getting a meaningful result.
True enough. But let me suggest something, assuming I don't make a
mistake in my reasoning before doing so.

If p is a pointer pointing to a memory region of sufficient size,

(p+5)==(p+5*siz eof(*p))

right?

No. However,

(char *)(p + 5) == (char *)p + 5 * sizeof *p
Likewise for p-5. Then (I suggest),

(p*5)==(5*sizeo f(*p))

would be sensible. Not needed, but meaningful, yes?

It doesn't seem particularly meaningful to me and I don't see why you
think it follows from your first example. Why does `p' change into
'sizeof(*p)' as the operand of binary '*'?

Jeremy.
Nov 14 '05 #36
Keith Thompson wrote:

The =+ syntax was dropped long before ISO C; it had vanished by the
time K&R1 was published.

Yes, my copy of K&R1 has this listed near the end of the Reference
Manual (appendix A) under "Anachronis ms". There is only one other thing
listed in this section: An initialization syntax that looks like this

int x 1;

int x = 1;

This is an aspect of "old C" that I've never heard mentioned anywhere else.

-Kevin
--
My email address is valid, but changes periodically.
Nov 14 '05 #37
On Wed, 07 Jan 2004 19:57:00 GMT
Kevin Goodsell <us************ *********@never box.com> wrote:
Flash Gordon wrote:

It's not holding your hand, it's just not providing something that
makes no sense. You can always side-step the limitation by casting
the pointers to long long and multiplying them, although there is no
guarantee that they will actually fit in to a long long.

FYI, there is a guarantee in C99 that an object pointer will fit in a
intptr_t, if that type is provided.

However, if it does not mandate the provision of intptr_t then it does
not help :-)
--
Flash Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spam, it is real and I read it.
Nov 14 '05 #38
Flash Gordon wrote:
On Wed, 07 Jan 2004 19:57:00 GMT
Kevin Goodsell <us************ *********@never box.com> wrote:

FYI, there is a guarantee in C99 that an object pointer will fit in a
intptr_t, if that type is provided.

However, if it does not mandate the provision of intptr_t then it does
not help :-)

I *thought* that it required intptr_t on implementations that have a
wide enough integer type, but I didn't see this requirement when I
checked the (draft) standard earlier today. I may have confused it with
the exact-width integer types, a few of which are required if and only
if the implementation has integer types of the appropriate sizes.

Optional types are of somewhat questionable usefulness. Code intended to
be strictly portable obviously can't use them. On the other hand, before
the introduction of these types implementations were already free to
choose whether or not to support things like an integer type that can
store a pointer value without loss, or an integer with exactly 32 bits.
Code which relied on things like these was already non-portable - these
types actually provide a way to make it /more/ portable (though still
not fully portable) because there's no question about which type to
choose. You /know/ that the appropriate 32-bit type is int32_t, so you
don't have to try to guess whether it will be int or long.

It also allows non-portable code to fail at compile time rather than
being broken at run-time if the implementation can't properly support it.

-Kevin
--
My email address is valid, but changes periodically.
Nov 14 '05 #39
Christopher Benson-Manica <at***@nospam.c yberspace.org> writes:
Keith Thompson <ks***@mib.or g> spoke thus:
Because you *can't* multiply two pointers, or an int and a pointer,
and stand a chance at getting a meaningful result.
True enough. But let me suggest something, assuming I don't make a
mistake in my reasoning before doing so.

If p is a pointer pointing to a memory region of sufficient size,

(p+5)==(p+5*siz eof(*p))

right? Likewise for p-5. Then (I suggest),

Um, no. If I understand what you're trying to say, the "+" on the
left side indicates pointer arithmetic as defined by C, and the "+" on
the right side indicates a different kind of pointer arithmetic that
counts by bytes, not by whatever object type p points to.

Note that, if both "+" operators meant the same thing, and the
expression were treated as a mathematical equation, you could subtract
p from each side and divide by 5, yielding 1 == sizeof(*p). And in
fact your original expression is true if and only if sizeof(*p) == 1
(assuming that p+5 is a valid pointer).

The correct way to express what you're trying to say (assuming that p
is a pointer to FOO, and assuming that FOO is an object type) is
something like this:

p+5 == (FOO*)((char*)p + 5*sizeof(*p))
(p*5)==(5*sizeo f(*p))

would be sensible. Not needed, but meaningful, yes?

I don't think so. It looks like you're trying to take your original
equation and replace "+" with "*", but you quietly dropped the "p+" on
the right hand side. (Or maybe I misunderstood your derivation.) In
any case, making a pointer value decay to the size of what it points
to if it's the operand of a multiplication operator (and not if it's
the operand of an addition or subtraction operator) seems
counterintuitiv e and not terribly useful. The language doesn't need
another way to say 5*sizeof(*p) that badly.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #40

This thread has been closed and replies have been disabled. Please start a new discussion.