By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,423 Members | 1,327 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,423 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
Share this Question
Share on Google+
87 Replies


P: n/a
August Derleth wrote:

(snip)
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.


(snip)

I believe PL/I will let you take the square root of a struct, doing it
element by element. You can also take the square root of a character
string if it has a numeric value.

I wonder why C doesn't allow that.

-- glen

Nov 14 '05 #51

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Sean Kenwrick <sk*******@hotmail.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. 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.


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.

This interview was quite a long time ago (1989), but I remember it well
because of these 'trick' questions that I was asked about C. Perhaps they
were still using a compiler at the company that supported this old
syntax....

Sean
Nov 14 '05 #52

P: n/a
In article <QH**************@fe01.usenetserver.com> em***@for.address writes:
Keith Thompson wrote:

....
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.
Actually the high order 16 bits. The low order 48 bits are the memory
address.
(I actually don't know how much hardware support
there is for this format.)
None at all. There is *no* hardware support for 8 bit quantities.
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?


This would be with Cray's C compiler. I do not know whether there is gcc
support for the Cray. It would be a bit foolish to look for gcc on the
Cray as it certainly does not support vectorisation.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #53

P: n/a
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:


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


You cite the rule correctly:
"the intermediate expression (rcopy + q)
has the illegal form of (ptr + ptr)"
You make the observation, which corresponds to the rule:
"gcc rejected my construction"

Where do you get this erroneous notion from ? :
"the net expression is OK"

--
pete
Nov 14 '05 #54

P: n/a
glen herrmannsfeldt wrote:

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.


What's OK about it ?
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;


That last line of code is a syntax error.

--
pete
Nov 14 '05 #55

P: n/a
August Derleth <em***@for.address> writes:
Keith Thompson wrote:

[...]
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. :)


Which is one of the ways C is an improvement over BCPL. :-|

[...]
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 asn
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?


No, gcc doesn't support the Cray vector machines; Cray has its own C
compiler.

--
Keith Thompson (The_Other_Keith) 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 #56

P: n/a
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> spoke thus:
Christopher Benson-Manica wrote:

(p+5)==(p+5*sizeof(*p))

right?
No. However, (char *)(p + 5) == (char *)p + 5 * sizeof *p
1) p+5 and p+5*sizeof(*p) are valid constructions, correct?
2) I assume they do not compare as equal because of some implicit
conversion issues?
3) If 2, would you care to elaborate?
4) If 2 and 3, can you tell me what the Standard says...?
5) Does 5+p have the same semantics as p+5?

(thanks!)
(p*5)==(5*sizeof(*p))

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 '*'?


It would allow one to use

malloc( 5*p );

to allocate space for an array of 5 p's. Mostly I was just trying to
counter the suggestion that multiplying an integer and a pointer is a
conceptually meaningless endeavor...

--
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 #57

P: n/a
glen herrmannsfeldt <ga*@ugcs.caltech.edu> spoke thus:
I believe PL/I will let you take the square root of a struct, doing it
element by element. You can also take the square root of a character
string if it has a numeric value. I wonder why C doesn't allow that.


In that case,

struct p {
char *foo;
char bar;
int:3 baz;
int:2 quux;
};

would likely be quite a challenge to sqrt(). A lot of work for
implementors, certainly...

--
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 #58

P: n/a
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote:
glen herrmannsfeldt <ga*@ugcs.caltech.edu> spoke thus:
I believe PL/I will let you take the square root of a struct, doing it
element by element. You can also take the square root of a character
string if it has a numeric value. I wonder why C doesn't allow that.

In that case, struct p {
char *foo;
char bar;
int:3 baz;
int:2 quux;
}; would likely be quite a challenge to sqrt(). A lot of work for
implementors, certainly...


Fortunately sqrt will not have to deal with this struct because
it contains syntax errors. Bit-width should be specified for the
member, not its type.

--
Alex Monjushko (mo*******@hotmail.com)
Nov 14 '05 #59

P: n/a
Christopher Benson-Manica wrote:
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> spoke thus:
Christopher Benson-Manica wrote:
(p+5)==(p+5*sizeof(*p))

right?

No. However,


(char *)(p + 5) == (char *)p + 5 * sizeof *p

1) p+5 and p+5*sizeof(*p) are valid constructions, correct?


Yes. Both show pointer arithmetic. The integer added to the pointer p is
different in each case, so the result is presumably different.
2) I assume they do not compare as equal because of some implicit
conversion issues?
Not really... they don't compare equal for the same reason i+5 and i+5*4
don't compare equal when i is an integer.
3) If 2, would you care to elaborate?
4) If 2 and 3, can you tell me what the Standard says...?
5) Does 5+p have the same semantics as p+5?


Yes.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #60

P: n/a
pete wrote:
glen herrmannsfeldt wrote: (previously snipped discussion)
(snip)
Things get more interesting with pointers to larger types. int *b,*c;
char *a;

a=a+b-c;

That last line of code is a syntax error.


Yes. As the pointers have different units it wouldn't make
sense even though the overall relocation factor is 1.

Also, C requires pointer comparison, and I believe pointer
subtraction to be done with pointers to the same object.
Systems that keep track of memory in a segment/offset or
object reference/offset into object usually do pointer
subtraction only subtracting the offsets. Also, the
operators <, <=, >, >= usually only apply to the offset.

For a flat address space and only (char*) pointers you
might get the same result, with other pointer types or
other addressing methods you don't.

-- glen

Nov 14 '05 #61

P: n/a
Christopher Benson-Manica wrote:

I wrote:
I believe PL/I will let you take the square root of a struct, doing it
element by element. You can also take the square root of a character
string if it has a numeric value. I wonder why C doesn't allow that.
In that case, struct p {
char *foo;
char bar;
int:3 baz;
int:2 quux;
};

would likely be quite a challenge to sqrt(). A lot of work for
implementors, certainly...


Well, C in general doesn't do array or struct expressions. At some
point in C history the ability to pass a struct as a function argument
was added (instead of only struct pointers).

I don't believe PL/I will do sqrt() on a pointer variable, and
I wouldn't want to see the result if it did. The rest should
be fine, though. PL/I has character string variables instead
of character arrays, and will convert between them and numeric
values, as needed.

How about a C for loop such as:

char s[100];
for(strcpy(s,"1"); strcmp(s,"100")<0; sprintf(s,"%3d",atoi(s)+1)) ;

-- glen

Nov 14 '05 #62

P: n/a

On Thu, 8 Jan 2004, glen herrmannsfeldt wrote:

How about a C for loop such as:

char s[100];
for(strcpy(s,"1"); strcmp(s,"100")<0; sprintf(s,"%3d",atoi(s)+1)) ;


assert(0 == strcmp(s, "2"));

[Whoops.]

-Arthur
Nov 14 '05 #63

P: n/a
"Sean Kenwrick" <sk*******@hotmail.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message

[...]
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.

This interview was quite a long time ago (1989), but I remember it well
because of these 'trick' questions that I was asked about C. Perhaps they
were still using a compiler at the company that supported this old
syntax....


That's quite possible. In that case, the "=+" syntax and the
ambiguities it can introduce are certainly something you would have
needed to know for the job -- but it would have made a lot more sense
for them to just tell you about it, rather than expecting you to know
about it in the first place.

<OT>
On the other hand, diplomacy is also a valuable job skill.
</OT>

--
Keith Thompson (The_Other_Keith) 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 #64

P: n/a
"Dik T. Winter" <Di********@cwi.nl> writes:
In article <QH**************@fe01.usenetserver.com> em***@for.address writes:
> Keith Thompson wrote:

...
> > 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.
Actually the high order 16 bits. The low order 48 bits are the memory
address.


I just ran an experiment on a Cray SV1. For a char* pointer, the
3-bit byte offset is in the high-order 3 bits of the 64-bit word.
I can believe, though, that the word address occupies only the 48
low-order bits, and the other 13 bits are always zero.

It's tempting to suggest that it would have made more sense to use the
entire upper 16 bits as a byte offset, but I suppose it's no more
difficult to extract the high-order 3 bits than to extract the
high-order 16 bits.

Here's the program:
========================================
#include <stdio.h>

int main(void)
{
char buf[100];
int i;

for (i = 0; i <= 8; i ++) {
printf("buf+%d = [%022p]\n", i, (void*)(buf + i));
}
return 0;
}
========================================

Here's the output:
========================================
buf+0 = [0000000000000000107531]
buf+1 = [0200000000000000107531]
buf+2 = [0400000000000000107531]
buf+3 = [0600000000000000107531]
buf+4 = [1000000000000000107531]
buf+5 = [1200000000000000107531]
buf+6 = [1400000000000000107531]
buf+7 = [1600000000000000107531]
buf+8 = [0000000000000000107532]
========================================

The "%p" conversion specifier formats addresses in octal. I used
"%022p" to make everything line up nicely; I'm not sure how portable
it is, but it works here.
> > (I actually don't know how much hardware support
> > there is for this format.)
None at all. There is *no* hardware support for 8 bit quantities.


Thanks, that's an interesting thing to know. I tried looking at an
assembly listing to figure out how the operations are implemented, but
Cray's assembler syntax is a bit odd, and I've never taken the time to
learn it.
> > 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?


This would be with Cray's C compiler. I do not know whether there is gcc
support for the Cray. It would be a bit foolish to look for gcc on the
Cray as it certainly does not support vectorisation.


Right, but not everything that runs on a Cray uses vectorization.
There's an entire Unix-like operating system with all the usual
utilities. But porting gcc to Cray vector machines, even without
vector support, apparently is more work than anyone has been willing
to do. (Since I'm not willing or able to do the work myself, I'm
certainly not criticizing anyone else for not doing it.)

There's also no gcc for the Cray T3E, even though it uses Alpha CPUs
rather than one of Cray's custom vector thingies.

Interesting though all this stuff is (at least to me), the only really
topical point being made is that some C implementations are weirder
than most poeple would expect. If you stick to what's guaranteed by
the standard, you can write code that's portable even to exotic
implementations. If you make implicit assumptions that happen to be
correct for every machine you've ever used (like "incrementing the
integer representation of a pointer makes it point to the next byte in
memory"), you can get into trouble.

(Arguably, it would actually have made a lot more sense for Cray's C
implementation to have CHAR_BIT==64, but that would have broken a lot
more existing software than the funny byte pointers did. I doubt that
the Unix port would have been as successful.)

--
Keith Thompson (The_Other_Keith) 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 #65

P: n/a
Christopher Benson-Manica <at***@nospam.cyberspace.org> writes:
[...]
1) p+5 and p+5*sizeof(*p) are valid constructions, correct?
Yes, but they have different meanings (unless sizeof(*p) happens to be 1).
2) I assume they do not compare as equal because of some implicit
conversion issues?
3) If 2, would you care to elaborate?
4) If 2 and 3, can you tell me what the Standard says...?
No, there's no implicit conversion, it's just the way pointer arithmetic
is defined.

C99 6.5.5 "Multiplicative operators", paragraph 8:

When an expression that has integer type is added to or subtracted
from a pointer, the result has the type of the pointer operand. If
the pointer operand points to an element of an array object, and
the array is large enough, the result points to an element offset
from the original element such that the difference of the
subscripts of the resulting and original array elements equals the
integer expression. In other words, if the expression P points to
the i-th element of an array object, the expressions (P)+N
(equivalently, N+(P)) and (P)-N (where N has the value n) point
to, respectively, the i+n-th and i-n-th elements of the array
object, provided they exist. Moreover, if the expression P points
to the last element of an array object, the expression (P)+1
points one past the last element of the array object, and if the
expression Q points one past the last element of an array object,
the expression (Q)-1 points to the last element of the array
object. If both the pointer operand and the result point to
elements of the same array object, or one past the last element of
the array object, the evaluation shall not produce an overflow;
otherwise, the behavior is undefined. If the result points one
past the last element of the array object, it shall not be used as
the operand of a unary * operator that is evaluated.
5) Does 5+p have the same semantics as p+5?


Yes, addition is commutative. (Note that C addition is commutative
because the standard says so; it could as easily have said that
pointer+integer is legal, but integer+pointer is not. That would also
have made silly things like 5["abcdef"] illegal; see question 6.11 in
the C FAQ.)

--
Keith Thompson (The_Other_Keith) 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 #66

P: n/a
In article <Tw*************@fe01.usenetserver.com>,
August Derleth <em***@for.address> wrote:
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.


I'm not saying it would be. I'm just saying that some languages allow
it, and that I'm surprised that C isn't one of them.


If something cannot possibly be meaningful, then why would you want
to be able to write code that does it?

Nov 14 '05 #67

P: n/a
In article <eJ9Lb.313279$_M.1812548@attbi_s54> glen herrmannsfeldt <ga*@ugcs.caltech.edu> writes:
I believe PL/I will let you take the square root of a struct, doing it
element by element. You can also take the square root of a character
string if it has a numeric value.

I wonder why C doesn't allow that.


I think numerical mathematicians would complain when the struct is
called "complex".
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #68

P: n/a
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
"Dik T. Winter" <Di********@cwi.nl> writes:
In article <QH**************@fe01.usenetserver.com> em***@for.address writes:
> Keith Thompson wrote: ...
> > 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.


Actually the high order 16 bits. The low order 48 bits are the memory
address.


I just ran an experiment on a Cray SV1. For a char* pointer, the
3-bit byte offset is in the high-order 3 bits of the 64-bit word.
I can believe, though, that the word address occupies only the 48
low-order bits, and the other 13 bits are always zero.


O well, I must have disremembered. Anoyhow the other 13 bits are always
zero.
It's tempting to suggest that it would have made more sense to use the
entire upper 16 bits as a byte offset, but I suppose it's no more
difficult to extract the high-order 3 bits than to extract the
high-order 16 bits.
Indeed, no problem.
> > (I actually don't know how much hardware support
> > there is for this format.)


None at all. There is *no* hardware support for 8 bit quantities.


Thanks, that's an interesting thing to know. I tried looking at an
assembly listing to figure out how the operations are implemented, but
Cray's assembler syntax is a bit odd, and I've never taken the time to
learn it.


I never thought Cray assembler a bit odd. I have programmed quite a bit
in it. It reminds one of the assembler for the CDC 7600. Not so much of
a surprise.
This would be with Cray's C compiler. I do not know whether there is gcc
support for the Cray. It would be a bit foolish to look for gcc on the
Cray as it certainly does not support vectorisation.


Right, but not everything that runs on a Cray uses vectorization.
There's an entire Unix-like operating system with all the usual
utilities.


Yup, I have used it.
But porting gcc to Cray vector machines, even without
vector support, apparently is more work than anyone has been willing
to do. (Since I'm not willing or able to do the work myself, I'm
certainly not criticizing anyone else for not doing it.)
Porting any untility to the Cray is much work. I have helped somebody
port a derivate of the Bourne shell to the Cray. I have ported the
Korn shell to it. Not entirely simple. The main reason being that
they assumed non-portable things (like being able to use the low
order bit of an int pointer as a flag).
There's also no gcc for the Cray T3E, even though it uses Alpha CPUs
rather than one of Cray's custom vector thingies.
There probably is one, but it will use only one processor. I would
think that the plain Alpha gcc would work.
Interesting though all this stuff is (at least to me), the only really
topical point being made is that some C implementations are weirder
than most poeple would expect.
There are (were) weirder machines available. DG's MV series...
(Arguably, it would actually have made a lot more sense for Cray's C
implementation to have CHAR_BIT==64, but that would have broken a lot
more existing software than the funny byte pointers did. I doubt that
the Unix port would have been as successful.)


I think the software would have broken just as much. I understand the
Unix port has been a nearly complete rewrite of almost all utilities.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #69

P: n/a

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote
[..]
In that case,

struct p {
char *foo;
char bar;
int:3 baz;
int:2 quux;
};


Is this a valid declaration of bit-field members?
Should it not have been

struct p {
char *foo;
char bar;
int baz :3;
int quux :2;
};
--
vijay-z.
Nov 14 '05 #70

P: n/a
"Dik T. Winter" <Di********@cwi.nl> writes:
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
> "Dik T. Winter" <Di********@cwi.nl> writes: [...]
> > None at all. There is *no* hardware support for 8 bit quantities. >
> Thanks, that's an interesting thing to know. I tried looking at an
> assembly listing to figure out how the operations are implemented, but
> Cray's assembler syntax is a bit odd, and I've never taken the time to
> learn it.


I never thought Cray assembler a bit odd. I have programmed quite a bit
in it. It reminds one of the assembler for the CDC 7600. Not so much of
a surprise.


Well, it's odd compared to the assembler syntaxes I'm familiar with.

[...]
> But porting gcc to Cray vector machines, even without
> vector support, apparently is more work than anyone has been willing
> to do. (Since I'm not willing or able to do the work myself, I'm
> certainly not criticizing anyone else for not doing it.)


Porting any untility to the Cray is much work. I have helped somebody
port a derivate of the Bourne shell to the Cray. I have ported the
Korn shell to it. Not entirely simple. The main reason being that
they assumed non-portable things (like being able to use the low
order bit of an int pointer as a flag).


It depends on the utility, I suppose. I've recompiled quite a few
things on Crays without too much difficulty, but probably quite a few
of them had already been ported (sometimes with masses of #ifdefs).

One example: as far as I know, Perl compiles out of the box.

[...] I think the software would have broken just as much. I understand the
Unix port has been a nearly complete rewrite of almost all utilities.


Hmm, that's surprising.

--
Keith Thompson (The_Other_Keith) 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 #71

P: n/a
Arthur J. O'Dwyer wrote:
On Thu, 8 Jan 2004, glen herrmannsfeldt wrote:
How about a C for loop such as:

char s[100];
for(strcpy(s,"1"); strcmp(s,"100")<0; sprintf(s,"%3d",atoi(s)+1)) ;

assert(0 == strcmp(s, "2"));

[Whoops.]


I presume you didn't run the loop, though you don't say the
results of the assert.

The "%3d" is important to make it work, along with a character
set where ' ' < '1'.

-- glen

Nov 14 '05 #72

P: n/a

On Fri, 9 Jan 2004, glen herrmannsfeldt wrote:

Arthur J. O'Dwyer wrote:
On Thu, 8 Jan 2004, glen herrmannsfeldt wrote:
char s[100];
for(strcpy(s,"1"); strcmp(s,"100")<0; sprintf(s,"%3d",atoi(s)+1)) ;


assert(0 == strcmp(s, "2"));

[Whoops.]


I presume you didn't run the loop, though you don't say the
results of the assert.

The "%3d" is important to make it work, along with a character
set where ' ' < '1'.


Hmm... if it weren't for that last assumption, I'd have to say
"move that Whoops down two levels of quotation." :( But you could
actually fix the code, couldn't you, by changing "%3d" to "%03d".
Then it would work no matter what value your system gave to ' '!

atoi("010") == 10, right? What standard functions treat "010"
as octal? Could someone with a fast connection and 'grep' please
give a list of those circumstances? (I think there's some 'scanf'
format that understands 0x and 0, isn't there?)

-Arthur
Nov 14 '05 #73

P: n/a
Arthur J. O'Dwyer wrote:

atoi("010") == 10, right? What standard functions treat "010"
as octal? Could someone with a fast connection and 'grep' please
give a list of those circumstances? (I think there's some 'scanf'
format that understands 0x and 0, isn't there?)


%i does for scanf. The various strto* functions can also, if you give
them a base of 0.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #74

P: n/a
Kevin Goodsell wrote:
Arthur J. O'Dwyer wrote:

atoi("010") == 10, right? What standard functions treat "010"
as octal? Could someone with a fast connection and 'grep' please
give a list of those circumstances? (I think there's some 'scanf'
format that understands 0x and 0, isn't there?)

%i does for scanf. The various strto* functions can also, if you give
them a base of 0.


Also: atoi always uses base 10 (as if calling strtol() with 10 as the
base argument), so your first statement is correct.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #75

P: n/a
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
"Dik T. Winter" <Di********@cwi.nl> writes:
In article <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes: ....
> Cray's assembler syntax is a bit odd, and I've never taken the time to
> learn it.
I never thought Cray assembler a bit odd. I have programmed quite a bit
in it. It reminds one of the assembler for the CDC 7600. Not so much of
a surprise.


Well, it's odd compared to the assembler syntaxes I'm familiar with.


Ah, I know stranger syntaxes than Cray's. Here a short routine that sets
the register at 1 when the current value >= +0 and to -1 when it is <= 0:
F = F, P
Y, F = 1
N, F = -1
The keyword syntax as you know it is one of the many syntaxes around.
Porting any untility to the Cray is much work. I have helped somebody
port a derivate of the Bourne shell to the Cray. I have ported the
Korn shell to it. Not entirely simple. The main reason being that
they assumed non-portable things (like being able to use the low
order bit of an int pointer as a flag).


It depends on the utility, I suppose. I've recompiled quite a few
things on Crays without too much difficulty, but probably quite a few
of them had already been ported (sometimes with masses of #ifdefs).


It also depends on the time-span. When Cray started developing Unicos
(early 1990's I think), there was not yet really much consideration for
portability in the source of utilities. Especially to machines that
were not Vax lookalikes.

One example: as far as I know, Perl compiles out of the box.


Probably. Currently utilities are much better programmed. But I know
that (for instance) wuftpd will not work out of the box on a machine
where the bit pattern of the null pointer is not all zero bits and
NULL is defined as (void *)NULL. However, currently there are still
utilities that assume that if you cast a pointer to char to a pointer
to int and back again to a pointer to char, this may fail (and not
only on the Cray, but with the C compiler I used on the Cray it would
certainly fail). And there is still software around that makes this
assumption. (Of course it would also fail on a DG MV.) On the other
hand, compiling out of the box does *not* mean that it will work.
I think the software would have broken just as much. I understand the
Unix port has been a nearly complete rewrite of almost all utilities.


Hmm, that's surprising.


Not so very much. When Unicos was started, portability of source in C
was still in its infancy. Take the source for the Bourne shell for
instance. It would compile out of the box, but it would not work at
all (its memory allocation and deallocation routines would fail amongst
other problems %). There were too many utilities where the source assumes
something special about the machine which is false on a slightly esoteric
architectures. Getting Unix and all utilities to work on a 80286 also
has taken quite some rewriting, I understand.
(And there still are.)
-
% The Korn shell I ported to the Cray had no longer these problems, because
there were #ifdefs for the Cray in the source. I no longer have the source
available, but if I remember correctly, there were quite a few. However,
many of those #ifdefs would not have been needed if portability had been
the first concern.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #76

P: n/a
Arthur J. O'Dwyer wrote:
On Fri, 9 Jan 2004, glen herrmannsfeldt wrote:
(snip of for loop using strings)
The "%3d" is important to make it work, along with a character
set where ' ' < '1'.

Hmm... if it weren't for that last assumption, I'd have to say
"move that Whoops down two levels of quotation." :( But you could
actually fix the code, couldn't you, by changing "%3d" to "%03d".
Then it would work no matter what value your system gave to ' '! atoi("010") == 10, right? What standard functions treat "010"
as octal? Could someone with a fast connection and 'grep' please
give a list of those circumstances? (I think there's some 'scanf'
format that understands 0x and 0, isn't there?)


I wasn't too worried, ' '<'1' in both ASCII and EBCDIC.

Anyway, with the right number of blanks, you can do this with
a PL/I DO statement.

DCL S CHAR(100) VARYING;
DO S='1' TO ' 100' BY '1';
PUT SKIP LIST(SQRT(S));
END;

-- glen

Nov 14 '05 #77

P: n/a
"Keith Thompson" <ks***@mib.org> wrote:
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.


We still use one at my work. There used to be a lot of places in the code
that looked like this:

something =NULL;
other =NULL;
whatever =&something_else;

Please note lots of spaces before '=' but none after it. It was the
prefered style of the programmer who wrote it. After the warnings, she
corrected ti to:

something =NULL;
other =NULL;
whatever =(&something_else);

;-)
Nov 14 '05 #78

P: n/a
"glen herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote:
I have used compilers that allowed them for compatibility. I still
always put a space between = and -, like i= -1; to be sure.


I always use spaces around *all* binary (or ternary) operators.
For clarity.

So,
i = -1;
a = m * n + 4;
etc.

But I appreciate that it's just a matter of style.

Peter
Nov 14 '05 #79

P: n/a
"Eric Sosman" <Er*********@sun.com> wrote:
Vijay Kumar R Zanvar wrote:
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:


<big snip (good examples BTW)>
- 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.


No, it could not be an area. For two reasons:
1. Where is a guarante that Main Street and El Casino Real are
perpendicular? What if they are parallel? Or even in two different towns, or
even countries?
2. Even if they were perpendicular, you would need a range on each side, so
perhaps "123 to 234 Main Street times 89 to 98 El Camino Real", which boils
down to multiplication of integers ;-)

The upshot is, Ben was right.

Peter
Nov 14 '05 #80

P: n/a
Peter Pichler <pi*****@pobox.sk> scribbled the following:
"Eric Sosman" <Er*********@sun.com> wrote:
Vijay Kumar R Zanvar wrote:
> 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: <big snip (good examples BTW)> - 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.

No, it could not be an area. For two reasons:
1. Where is a guarante that Main Street and El Casino Real are
perpendicular? What if they are parallel? Or even in two different towns, or
even countries?
2. Even if they were perpendicular, you would need a range on each side, so
perhaps "123 to 234 Main Street times 89 to 98 El Camino Real", which boils
down to multiplication of integers ;-) The upshot is, Ben was right.


If Main Street and El Camino Real (not "El Casino Real") are not
parallel (they don't need to be perpendicular, just not parallel),
it's easy to multiply those locations.
Draw a line crossing 123 Main Street, perpendicular to El Camino Real.
Draw a line crossing 89 El Camino Real, perpendicular to Main Street.
The product of those addresses is the intersection point of those two
lines.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Holy Banana of this, Sacred Coconut of that, Magic Axolotl of the other."
- Guardian in "Jinxter"
Nov 14 '05 #81

P: n/a
Joona I Palaste <pa*****@cc.helsinki.fi> scribbled the following:
Peter Pichler <pi*****@pobox.sk> scribbled the following:
"Eric Sosman" <Er*********@sun.com> wrote:
Vijay Kumar R Zanvar wrote:
> 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:
<big snip (good examples BTW)> - 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.
No, it could not be an area. For two reasons:
1. Where is a guarante that Main Street and El Casino Real are
perpendicular? What if they are parallel? Or even in two different towns, or
even countries?
2. Even if they were perpendicular, you would need a range on each side, so
perhaps "123 to 234 Main Street times 89 to 98 El Camino Real", which boils
down to multiplication of integers ;-) The upshot is, Ben was right.

If Main Street and El Camino Real (not "El Casino Real") are not
parallel (they don't need to be perpendicular, just not parallel),
it's easy to multiply those locations.
Draw a line crossing 123 Main Street, perpendicular to El Camino Real.
Draw a line crossing 89 El Camino Real, perpendicular to Main Street.
The product of those addresses is the intersection point of those two
lines.


No, that's not right, after all. There are two correct ways to draw
those lines.
1) Draw a line crossing 123 Main Street, parallel to El Camino Real.
Draw a line crossing 89 El Camino Real, parallel to Main Street.
2) Draw a line crossing 123 Main Street, perpendicular to Main Street.
Draw a line crossing 89 El Camino Real, perpendicular to El Camino Real.
The way I used above would put the intersection point in the wrong
place. If Main Street and El Camino Real were perpendicular, it would
*always* put the intersection point at the intersection point of the
streets themselves, regardless of the addresses.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I said 'play as you've never played before', not 'play as IF you've never
played before'!"
- Andy Capp
Nov 14 '05 #82

P: n/a
Vijay Kumar R Zanvar <vi*****@hotpop.com> spoke thus:
"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote (erroneously!)
struct p {
char *foo;
char bar;
int:3 baz;
int:2 quux;
};

Is this a valid declaration of bit-field members?


Nope... It's quite wrong, and I am justifiably embarassed to have
written it ;(

--
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 #83

P: n/a
Peter Pichler wrote:
I always use spaces around *all* binary (or ternary) operators.
For clarity.

So,
i = -1;
a = m * n + 4;
etc.

But I appreciate that it's just a matter of style.


I usually do that too, except when the operator is used as an array
index:
j = i + 1; /* here I do */

a = array[i+1]; /* here I don't */
Why? I don't know exactly, compactness I suspose. It just "looks right"
in the context.

Brian Rodenborn
Nov 14 '05 #84

P: n/a
> char *rcopy, *q, *r;
foobar(rcopy + q - r);

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.


The portability and overflow problems of your idea can be highlighted
by explicitly writing what you are proposing:

(char *)( (uint)rcopy + (uint)q - (uint)r )
Nov 14 '05 #85

P: n/a
Default User wrote:
Peter Pichler wrote:

But I appreciate that it's just a matter of style.


I usually do that too, except when the operator is used as an array
index:
j = i + 1; /* here I do */

a = array[i+1]; /* here I don't */
Why? I don't know exactly, compactness I suspose. It just "looks right"
in the context.


I usually use spaces, but sometimes it seems more natural to leave them
out. One case where I often leave out spaces is when I'm using two
binary operators, in which case I'll have the one with higher precedence
closer to it's operands (which reflects the notion of the operator
"binding more tightly):

a*b + c

But I don't have any hard rules - I do whatever feels right or (in my
opinion) makes the code look cleaner.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #86

P: n/a
"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:84**************************@posting.google.c om...
(previous poster's name snipped by Old Wolf)
char *rcopy, *q, *r;
foobar(rcopy + q - r);

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.
The portability and overflow problems of your idea can be highlighted
by explicitly writing what you are proposing:

(char *)( (uint)rcopy + (uint)q - (uint)r )


Are you trying to say that the two examples are equivalent? Because they
are certainly not, yours being downright wrong.

The first example will be expressed more clearly as
foobar(rcopy + (q - r));
but the poster, whoever he or she was, presumably knew that already.
The parentheses around (q - r) are necessary, because + and - associate
left to right, so
foobar(rcopy + q - r);
parses as
foobar((rcopy + q) - r);
which is a constraint violation (adding two pointers).

Peter Pichler
Nov 14 '05 #87

P: n/a

On Mon, 12 Jan 2004, Joona I Palaste wrote:

Joona I Palaste <pa*****@cc.helsinki.fi> scribbled the following:
Peter Pichler <pi*****@pobox.sk> scribbled the following:
"Eric Sosman" <Er*********@sun.com> wrote:
Vijay Kumar R Zanvar wrote:
> Why multiplication of pointers is not allowed?

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 computing "123 Main Street times 89 El Camino Real" makes no
sense. Perhaps the result might be considered a kind of "area," No, it could not be an area.

[Joona wrote:] If Main Street and El Camino Real (not "El Casino Real") are not
parallel (they don't need to be perpendicular, just not parallel),
it's easy to multiply those locations.
1) Draw a line crossing 123 Main Street, parallel to El Camino Real.
Draw a line crossing 89 El Camino Real, parallel to Main Street. [Find those lines' point of intersection.]
2) Draw a line crossing 123 Main Street, perpendicular to Main Street.
Draw a line crossing 89 El Camino Real, perpendicular to El Camino Real.

[Find those lines' point of intersection.]

Neither of those operations behaves anything like real multiplication
[by which I mean either * over the real numbers, or real-life
multiplication; take your pick]. There's no 1 and no 0; each number
has several different numbers by which you can multiply it to get the
same number back; and so forth.
It's an interesting and probably useful operation, but I don't see
any way to map it onto "multiplication" in the usual sense.

[Oh, and almost-on-topic, it's worth noting that in most computer
architectures, Main Street and El Camino Real *are* parallel...]

-Arthur
Nov 14 '05 #88

87 Replies

This discussion thread is closed

Replies have been disabled for this discussion.