445,655 Members | 959 Online
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

Why multiplication not allowed?

 P: n/a 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 find an answer. -- Vijay Kumar R Zanvar My Home Page - http://www.geocities.com/vijoeyz/ Nov 14 '05 #1
87 Replies

 P: n/a "Vijay Kumar R Zanvar" writes: Why multiplication of pointers is not allowed? Till now I only know this, but not the reason why! What would multiplication of pointers mean? Nov 14 '05 #2

 P: n/a "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: Why multiplication of pointers is not allowed? Till now I only know this, but not the reason why! What would multiplication of pointers mean? #include #include int main ( void ) { int i = 10; int *k = &i, *j = &i; k = k * j; return EXIT_SUCCESS; } This gives an error: ptr_mul.c: In function `main': ptr_mul.c:10: error: invalid operands to binary * Nov 14 '05 #3

 P: n/a "Vijay Kumar R Zanvar" writes: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: Why multiplication of pointers is not allowed? Till now I only know this, but not the reason why! What would multiplication of pointers mean? #include #include int main ( void ) { int i = 10; int *k = &i, *j = &i; k = k * j; You mean *k = *k * *j; In other words, multiply `int's, not pointers to `int's. return EXIT_SUCCESS; } The difference between pointers and their referents is pretty fundamental. Have you considered reading a textbook or taking a class? -- "I don't have C&V for that handy, but I've got Dan Pop." --E. Gibbons Nov 14 '05 #4

 P: n/a "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... int i = 10; int *k = &i, *j = &i; k = k * j; You mean *k = *k * *j; In other words, multiply `int's, not pointers to `int's. Is the following code wrong? I mean, does it do the same? int* k =&i int* j=&i k* = k* * j* (It seems to me more readable than the above. I come from Pascal background) Nov 14 '05 #5

 P: n/a Vijay Kumar R Zanvar wrote: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu..."Vijay Kumar R Zanvar" writes: Why multiplication of pointers is not allowed?Till now I only know this, but not the reason why!What would multiplication of pointers mean? 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. 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. -Kevin -- My email address is valid, but changes periodically. To contact me please use the address from a recent posting. Nov 14 '05 #6

 P: n/a "Vijay Kumar R Zanvar" wrote: Why multiplication of pointers is not allowed? Jack lives at Westmoreland Street 12, London SW6 4E8. Jill lives at Rossinistraat 27b, 1287 CZ Amsterdam. Please multiply these addresses and let us know the result. Richard Nov 14 '05 #7

 P: n/a Julian Maisano wrote: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... > int i = 10; > int *k = &i, *j = &i; > > k = k * j; You mean *k = *k * *j; In other words, multiply `int's, not pointers to `int's. Is the following code wrong? I mean, does it do the same? int* k =&i int* j=&i k* = k* * j* Yes, it's wrong; no, it doesn't do the same thing; and no, it's not legal syntax. The last line parses as: k *= k * *j * That is, multiply k (a pointer!) by the contents of j, multiply /that/ by heaven knows what, and then use the result to multiply by k again, assigning the result to k. (It seems to me more readable than the above. I come from Pascal background) In C, the dereferencing operator comes before the pointer. C programmers are accustomed to this syntax, and find it perfectly readable. -- Richard Heathfield : bi****@eton.powernet.co.uk "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton Nov 14 '05 #8

 P: n/a Richard Heathfield wrote: Julian Maisano wrote: Is the following code wrong? I mean, does it do the same? int* k =&i int* j=&i k* = k* * j* Yes, it's wrong; no, it doesn't do the same thing; and no, it's not legal syntax. The last line parses as: k *= k * *j * It doesn't parse that way. The whitespace between '*' and '=' is significant, so i* = j; is also a syntax error. Jeremy. Nov 14 '05 #9

 P: n/a Jeremy Yallop wrote: Richard Heathfield wrote: Julian Maisano wrote: Is the following code wrong? I mean, does it do the same? int* k =&i int* j=&i k* = k* * j* Yes, it's wrong; no, it doesn't do the same thing; and no, it's not legal syntax. The last line parses as: k *= k * *j * It doesn't parse that way. The whitespace between '*' and '=' is significant, Indeed it is. Oops, sorry, darn and heck. (More or less in that order.) so i* = j; is also a syntax error. Right. -- Richard Heathfield : bi****@eton.powernet.co.uk "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton Nov 14 '05 #10

 P: n/a Vijay Kumar R Zanvar wrote: 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 find an answer. The result would be meaningless. An easy (but informal) way to understand this is to use an analogy: think of pointer values as street addresses. Then the following operations make sense: - Find the house at "123 Main Street." - To find the neigboring house, compute "123 Main Street plus one." (I'm ignoring such real-world intrusions as odd-even numbering schemes, discontinuities between city blocks, and so on: we're just exploring an imperfect analogy, after all.) - To find the distance between two Main Street addresses, compute "123 Main Street minus 189 Main Street," yielding "minus 66 lots." However, some other arithmetical operations make no sense at all: - Computing "123 Main Street plus 207 Main Street" produces no useful answer. - Computing "123 Main Street minus 123 Elm Street" produces no useful answer. - Similarly, computing "123 Main Street times 89 El Camino Real" makes no sense. Perhaps the result might be considered a kind of "area," but there seems to be no useful analogous concept to "area" in the addressing of memory- resident objects. - Finally, computing "123 Main Street times three" might possibly make sense, arriving at "369 Main Street." But such a definition carries a built- in assumption that Main Street is zero-based, and in a linear computer memory no more than one object can begin at "address zero." If you want to find the house three times as far from the start of the street, you really want to compute "Main Street Origin plus three times (123 Main Street minus Main Street Origin)." -- Er*********@sun.com Nov 14 '05 #11

 P: n/a "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: > Why multiplication of pointers is not allowed? > Till now I only know this, but not the reason why! What would multiplication of pointers mean? #include #include int main ( void ) { int i = 10; int *k = &i, *j = &i; k = k * j; You mean *k = *k * *j; In other words, multiply `int's, not pointers to `int's. Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; assuming k and j are pointers to ints that have been correctly initialized.... Sean Nov 14 '05 #12

 P: n/a On Tue, 6 Jan 2004, Sean Kenwrick wrote: Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; *k = k*//*j; Nov 14 '05 #13

 P: n/a On Tue, 6 Jan 2004, Jarno A Wuolijoki wrote: Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; *k = k*//*j; Should have engaged my brain. It starts a new one, duh. Nov 14 '05 #14

 P: n/a "Sean Kenwrick" writes: Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; There's no way to tell whether it's invalid unless we can see what follows it. -- "Welcome to the wonderful world of undefined behavior, where the demons are nasal and the DeathStation users are nervous." --Daniel Fox Nov 14 '05 #15

 P: n/a Sean Kenwrick scribbled the following: Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; assuming k and j are pointers to ints that have been correctly initialized.... Are you testing our knowledge? The C tokeniser thinks of the /* as the start of a comment, so it ends up being: *k = *k which is a syntax error because the lack of a terminating semicolon. Were you thinking of using it in some way like this? *k = *k/*j; /* make sure the value of *k stays in bounds */ +0; /* this is just a dummy */ -- /-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\ \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/ "As a boy, I often dreamed of being a baseball, but now we must go forward, not backward, upward, not forward, and always whirling, whirling towards freedom!" - Kang Nov 14 '05 #16

 P: n/a On Tue, 6 Jan 2004 12:37:08 +0530, "Vijay Kumar R Zanvar" wrote: 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 notfind an answer. Adding an int to a pointer results in pointing to something a specified distance further to the "right" in memory. Subtracting an int from a pointer results in pointing to something a specified distance further to the "left" in memory. Subtracting one pointer from another results in how far apart the two memory locations are. If your program and data were to be magically relocated as a unit in memory, each of the above expressions would still produce the same result. Until you can define a concept of either adding two pointers or multiplying two pointers that meets the constraint in the previous paragraph, the two operations make no sense. (Hint: others have thought this through and decided such a definition is either not possible or of no programming value.) <> Nov 14 '05 #17

 P: n/a > Why multiplication of pointers is not allowed? While I've never felt an urge to multiply pointers, there is a situation where adding them is quite legitimate: char *rcopy, *q, *r; . . . strcpy(rcopy, r); q = index(r, '*'); . . . /* Now point to the '*' in the copy */ foobar(rcopy + q - r); (Please don't write in to tell me I forgot to allocate space for rcopy, etc. This is just a minimal illustration of the point.) Although the intermediate expression (rcopy + q) has the illegal form of (ptr + ptr) the net expression is OK. I was disappointed when gcc rejected my construction like this, depending on how I parenthesized it. It seems like it shouldn't be hard to support. Yes, yes; the better parenthesization would also make the program more readable. Well nevermind .... James Nov 14 '05 #18

 P: n/a Kevin Goodsell wrote: Vijay Kumar R Zanvar wrote: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: Why multiplication of pointers is not allowed? Till now I only know this, but not the reason why! What would multiplication of pointers mean? 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? 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. As Kernighan said, "If you want PL/I, you know where to get it." In Forth, for example, a pointer is simply a bunch of bits on the stack, and you can do unto a pointer the same as you can do unto an int or anything else. The only extra feature is that, if you dereference it, you stand a good chance of getting something meaningful. I suppose if I want Forth, I know where to find it. Nov 14 '05 #19

 P: n/a On Wed, 07 Jan 2004 05:41:07 -0700 August Derleth wrote: Kevin Goodsell wrote: Vijay Kumar R Zanvar wrote: "Ben Pfaff" wrote in message news:87************@pfaff.stanford.edu... "Vijay Kumar R Zanvar" writes: > Why multiplication of pointers is not allowed?> Till now I only know this, but not the reason why! What would multiplication of pointers mean? 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? An pointer may have more bits than the ALU can cope with (it definitely does on some implementations) so why make a load of work for the implementation to do something that makes no sense? 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. As Kernighan said, "If you want PL/I, you know where to get it." 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. In Forth, for example, a pointer is simply a bunch of bits on the stack, and you can do unto a pointer the same as you can do unto an int or anything else. The only extra feature is that, if you dereference it, you stand a good chance of getting something meaningful. I suppose if I want Forth, I know where to find it. Indeed. -- 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 #20

 P: n/a Sean Kenwrick 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. Perhaps the members of this group could enlighten me about this since I 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 you about C. -- /-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\ \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/ "Parthenogenetic procreation in humans will result in the founding of a new religion." - John Nordberg Nov 14 '05 #21

 P: n/a "Joona I Palaste" wrote in message news:bt**********@oravannahka.helsinki.fi... Sean Kenwrick scribbled the following: Your solution above is correct but can you figure out why the following code is invalid (which it is): *k = *k/*j; assuming k and j are pointers to ints that have been correctly initialized.... Are you testing our knowledge? The C tokeniser thinks of the /* as the start of a comment, so it ends up being: *k = *k which is a syntax error because the lack of a terminating semicolon. Were you thinking of using it in some way like this? *k = *k/*j; /* make sure the value of *k stays in bounds */ +0; /* this is just a dummy */ Yeah you got it. By dividing *k by *j (without spaces) you get a syntax error. *k=*k/*j; you get a syntax error because the /* starts a comment. I was given this as a question in an interview for a job when I was a student (and I didn't get the question right (or the job!)). 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. Perhaps the members of this group could enlighten me about this since I think that this guy was just a complete idiot. The last question he asked was for me to declare a pointer to a funtion that returned a pointer to a function that returned a pointer to a char. Needless to say, without my K&R book to hand I messed that up as well (but by now I got the feeling that this guy was just being mean). In the end they gave the job to a female friend of mine who by her own admission was not a great programmer (she got me to do all her programming assignments in return for her doing all my essay assignments). Sean Nov 14 '05 #23

 P: n/a Sean Kenwrick wrote: [snip] 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. Perhaps the members of this group could enlighten me about this since I think that this guy was just a complete idiot. ISTR an article by one of the original C developers (Dennis Ritchie or perhap PJ Plauger) commenting on the /very/ early syntax of C. Specifically, the article said that the syntax i =+ j; had been considered as a way to express i = i + j; but was ultimately rejected because it was ambigious, and could be confused with i = j; If I read http://cm.bell-labs.com/cm/cs/who/dmr/chist.html correctly, it looks like this ambigious syntax was adopted from B into the earliest of C compilers, but later dropped (in 1976) before the adoption of "K&R C". [snip] -- Lew Pitcher, IT Consultant, Application Architecture Enterprise Technology Solutions, TD Bank Financial Group (Opinions expressed here are my own, not my employer's) Nov 14 '05 #24

 P: n/a Joona I Palaste wrote: Sean Kenwrick scribbled the following:But I think the reason I didn't get the job was because one of the otherquestions the interviewer asked me was to tell him what was wrong with thefollowing statement:i=+i;I said that there was nothing wrong with it, but the interviewer claimedthat it was an ambiguous statement because it could mean adding i to itseltor setting i to +i. I got into an argument with him saying that he mustbe confused with i+=i; but he was adament he was right and got annoyed thatI was disagreeing wih him.Afterwards I wondered whether this might have been some kind of syntax leftover from a very early incarnation of C which was subsequently dropped.Perhaps the members of this group could enlighten me about this since Ithink that this guy was just a complete idiot. Yes, this is an obsolete feature of C. =+ and =- originally meant the same as += and -=. And =* meant the same as *=, which made expressions like x=*p; needlessly ambiguous. splint, the lint-like program I use for laughs, still complains about things stemming from that wart. Whoever designed them that way must have been drinking something really strong. Indeed. Nov 14 '05 #25

 P: n/a On Wed, 07 Jan 2004 05:41:07 -0700, August Derleth 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 thatholds a certain string of bits or trits or decimal digits that composethat address. At this layer of abstraction, it's no different from anint or a float. Since I can multiply two ints and stand a good chance atgetting a meaningful result, why not two pointers? Or an int and a pointer? You didn't answer the question. What meaning would you ascribe to the result of the operation? -- Al Balmer Balmer Consulting re************************@att.net Nov 14 '05 #26

 P: n/a In article <26**************************@posting.google.com >, jd*********@yahoo.com (James Dow Allen) wrote: Why multiplication of pointers is not allowed? While I've never felt an urge to multiply pointers, there is a situation where adding them is quite legitimate: char *rcopy, *q, *r; . . . strcpy(rcopy, r); q = index(r, '*'); . . . /* Now point to the '*' in the copy */ foobar(rcopy + q - r); (Please don't write in to tell me I forgot to allocate space for rcopy, etc. This is just a minimal illustration of the point.) Although the intermediate expression (rcopy + q) has the illegal form of (ptr + ptr) the net expression is OK. If the intermediate expression is illegal, then the whole expression is illegal. Period. I was disappointed when gcc rejected my construction like this, depending on how I parenthesized it. It seems like it shouldn't be hard to support. Yes, yes; the better parenthesization would also make the program more readable. Well nevermind .... Adding pointers is still meaningless. What you're trying to do in this situation is get the difference of two pointers, and add that difference to another pointer. What you want is: rcopy + (q - r) Which is not ptr + ptr, it is ptr + ptrdiff. The better parenthesized version is not just "more readable", it is legal. Nov 14 '05 #27

 P: n/a Sean Kenwrick wrote: .... snip ... 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. Perhaps the members of this group could enlighten me about this since I think that this guy was just a complete idiot. You've got it. He had just been around from pre-standardization days. Note that proper civilized use of blanks untangles everything. -- Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 14 '05 #28

 P: n/a Richard Heathfield writes: The last question he asked was for me to declare a pointer to a funtion that returned a pointer to a function that returned a pointer to a char. Build up logically. We need a return value that is a pointer to a function that returns a pointer to a char: typedef char * (*pfrc)(); With that typedef, the solution becomes easy: pfrc (*solution)(); It's also easy without a helper type if you read (or build up) the declaration "from inside to outside" instead of from left to right: p The identifier `p'... *p ...is a pointer... (*p) () ...to a function... *(*p) () ...which returns a pointer... (*(*p) ()) () ...to a function... *(*(*p) ()) () ...which returns a pointer... char *(*(*p) ()) (); ...to `char'. Martin Nov 14 '05 #29

 P: n/a 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. To contact me please use the address from a recent posting. Nov 14 '05 #31

 P: n/a August Derleth writes: 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_Keith) ks***@mib.org San Diego Supercomputer Center <*> Schroedinger does Shakespeare: "To be *and* not to be" Nov 14 '05 #33

 P: n/a Keith Thompson 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*sizeof(*p)) right? Likewise for p-5. Then (I suggest), (p*5)==(5*sizeof(*p)) would be sensible. Not needed, but meaningful, yes? -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. Nov 14 '05 #35

 P: n/a Christopher Benson-Manica wrote: Keith Thompson 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*sizeof(*p)) right? No. However, (char *)(p + 5) == (char *)p + 5 * sizeof *p Likewise for p-5. Then (I suggest), (p*5)==(5*sizeof(*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

 P: n/a 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 "Anachronisms". There is only one other thing listed in this section: An initialization syntax that looks like this int x 1; instead of 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. To contact me please use the address from a recent posting. Nov 14 '05 #37

 P: n/a On Wed, 07 Jan 2004 19:57:00 GMT Kevin Goodsell 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

 P: n/a Flash Gordon wrote: On Wed, 07 Jan 2004 19:57:00 GMT Kevin Goodsell wrote:FYI, there is a guarantee in C99 that an object pointer will fit in aintptr_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. To contact me please use the address from a recent posting. Nov 14 '05 #39

 P: n/a Christopher Benson-Manica writes: Keith Thompson 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*sizeof(*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*sizeof(*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 counterintuitive and not terribly useful. The language doesn't need another way to say 5*sizeof(*p) that badly. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> Schroedinger does Shakespeare: "To be *and* not to be" Nov 14 '05 #40

 P: n/a Kevin Goodsell wrote in message news:... 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. More specifically, as an aside, the conversion back to an equivalent void * is guaranteed, something which isn't the case for other integer types, not even intmax_t. -- Peter Nov 14 '05 #41

 P: n/a Peter Nilsson wrote: Kevin Goodsell wrote in message news:...Flash Gordon wrote:It's not holding your hand, it's just not providing something that makesno sense. You can always side-step the limitation by casting thepointers to long long and multiplying them, although there is noguarantee that they will actually fit in to a long long.FYI, there is a guarantee in C99 that an object pointer will fit in aintptr_t, if that type is provided. More specifically, as an aside, the conversion back to an equivalent void * is guaranteed, something which isn't the case for other integer types, not even intmax_t. Yes, the standard only explicitly says you can convert from void* to intptr_t, then back to void* and the result will compare equal to the original void*. Other pointer types *should* also work (by which I mean that it would make sense, and people probably expect them to work), but I don't know if or where in the standard this is guaranteed. As for intmax_t, I would expect that it could be used in place of intptr_t as long as intptr_t exists - my reasoning being that the only thing which would prevent an integer type from holding a pointer value without loss is if the integer type is not wide enough, and intmax_t must be at least as wide as intptr_t. I don't know if that is correct, though. I should take a good look at the section of the standard dealing with conversion between integers and pointers, I guess. -Kevin -- My email address is valid, but changes periodically. To contact me please use the address from a recent posting. Nov 14 '05 #42

 P: n/a On Wed, 7 Jan 2004, Christopher Benson-Manica wrote: If p is a pointer pointing to a memory region of sufficient size, (p+5)==(p+5*sizeof(*p)) Mixing C and asm sides of brain?-) right? Likewise for p-5. Then (I suggest), (p*5)==(5*sizeof(*p)) would be sensible. Not needed, but meaningful, yes? Not really, but I'd imagine that sizeof(*(p*5)) == 5*sizeof(*p) would have some odd symmetry, if that's what you're after.. as in: pointers -> points (index, size) scalars -> vectors (index, 0) Nov 14 '05 #43

 P: n/a Alan Balmer wrote: You didn't answer the question. What meaning would you ascribe to the result of the operation? If you'd read on, you'd have seen that I really wouldn't have. Any more than I would have been able to ascribe meaning to the result of adding a random integral value to an arbitrary pointer. My whole point is that in some languages (not C, but C's immediate ancestors and some languages not connected with C at all), you can treat a pointer as you would any other integral type of that width. Which includes doing absolutely nonsensical things to it. Obviously, I'm in a minority here. I didn't expect it to be otherwise, given the bizarreness of the whole notion of multiplication being applied to pointers. Nov 14 '05 #44

 P: n/a Keith Thompson wrote: August Derleth writes:Kevin Goodsell wrote: [...]The question Ben is asking is, what would you propose pointermultiplication do? How would you define the operation? I can't thinkof any way in which multiplying a pointer by any other value wouldbe 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 memorythat holds a certain string of bits or trits or decimal digits thatcompose that address. At this layer of abstraction, it's no differentfrom an int or a float. Since I can multiply two ints and stand a goodchance at getting a meaningful result, why not two pointers? Or an intand a pointer? Because you *can't* multiply two pointers, or an int and a pointer, and stand a chance at getting a meaningful result. Which doesn't stop BCPL, for instance. :) 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. I know that. I am satisfied with the existing pointer arithmetic, acutally, even though I posited my remarks from the perspective of changing it. 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)). This is where my ideas about multiplication fall down in one respect: Addition (by positive and negative numbers) is scaled, but there's no meaningful way to scale multiplication. Or division, for that matter. And how would you scale the square root? We could invent ways, surely, but it's hardly worth it. (If you want to know, I was imagining pointers as being treated like integers in my imaginary C-like language.) 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. This is fascinating. Which compiler do you use? Does gcc support the Cray vector machines? It's fascinating, and it makes my ideas sound rather foolish. You could multiply two such pointers, but the machine-level semantics would always be in doubt and the result would be universally meaningless. 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. All of that is fair enough, and it's all I can reasonably expect. After all, the compiler won't hold my hand, will it? :) memcpy() seems like a somewhat sideways means of achieving this, but its semantics are obvious. Whereas the semantics of multiplying two pointers would not be. Nov 14 '05 #46

 P: n/a Barry Schwarz wrote: (snip) Why multiplication of pointers is not allowed?Till now I only know this, but not the reason why! (snip) Adding an int to a pointer results in pointing to something a specified distance further to the "right" in memory. Subtracting an int from a pointer results in pointing to something a specified distance further to the "left" in memory. Subtracting one pointer from another results in how far apart the two memory locations are. An expression could be properly absolute or relocatable, even if it contained multiplication of pointers. The number of uses are small enough that I am not surprised it isn't allowed. How about: char *s,*t; s=2*t-s; s=3*t-2*s; (I know some assemblers that allow relocation factors of -1, 0, 1, or 2.) -- glen Nov 14 '05 #47

 P: n/a Christopher Benson-Manica scribbled the following: Keith Thompson 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*sizeof(*p)) You mean (p+5)==((char *)p+5*sizeof(*p)), natch. -- /-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\ \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/ "My absolute aspect is probably..." - Mato Valtonen Nov 14 '05 #48

 P: n/a James Dow Allen wrote: While I've never felt an urge to multiply pointers, there is a situation where adding them is quite legitimate: char *rcopy, *q, *r; . . . strcpy(rcopy, r); q = index(r, '*'); . . . /* Now point to the '*' in the copy */ foobar(rcopy + q - r); My first C program using index, after using a similar function in other languages, did something like i=index(r,"*")-r; It made the NULL test more complicated, though. (Please don't write in to tell me I forgot to allocate space for rcopy, etc. This is just a minimal illustration of the point.) Although the intermediate expression (rcopy + q) has the illegal form of (ptr + ptr) the net expression is OK. Well, for (char*), ok. I was disappointed when gcc rejected my construction like this, depending on how I parenthesized it. It seems like it shouldn't be hard to support. Things get more interesting with pointers to larger types. int *b,*c; char *a; a=a+b-c; Remember that pointer addition is done in units of the type pointed to. Pointer-pointer is done so that the result is in such units. In this case, the result would be different. Also, consider that the int pointers could (illegally) point to non-aligned addresses. -- glen Nov 14 '05 #49

 P: n/a Joona I Palaste wrote: (snip) 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 you about C. I have used compilers that allowed them for compatibility. I still always put a space between = and -, like i= -1; to be sure. (I think the compiler gave a warning, though.) -- glen Nov 14 '05 #50

87 Replies