kendall@wjh12.UUCP (Sam Kendall) (10/05/84)
> "setjmp foo, *tmp; tmp = &foo;" is accepted with no complaints by my C > compiler (based on the Dennis Ritchie V7 PDP11 "cc"), as it should be, because > "tmp" and "&foo" have exactly the same (defined) type. > -- > Morris M. Keesan (I think you mean "jmp_buf foo, *tmp;".) The manual page implies that jmp_buf is typedef'd to an array type, since the calls wouldn't work if it weren't--you'd have to say "setjmp(&foo)" instead of "setjmp(foo)". Sure enough, all UNIX implementations make jmp_buf an array type. Now, the type of "tmp", pointer to array, is fine, but the expression "&foo" in "tmp = &foo" is not, because it is not legal to take the address of an array with the address-of operator (somewhere in the Ref Man it says an array is never an lvalue). "&array" works on Ritchie cc's anyway, as you note; but, quite properly, it won't work on others --in most PCC's, the "&" is ignored. "tmp = (jmp_buf *) foo" will work. Someone suggested that ATT allows assignment of jmp_buf's, etc.; this is totally wrong (unless he is using a bizarre internal dialect). > From: nazgul@apollo.uucp (Kee Hinckley) > The whole point of a typedef (in my mind at least) is to create a > level of abstraction that alleviates the need to learn what the machine/ > compiler architecture actually looks like. To a certain degree typedef > seems to succeed at this, but then it all falls apart. Any thoughts? I agree, although the point is also to abstract away from what the typedef'd type actually is, not just from the machine; the problem here is that arrays behave differently from other types in C, and you can get bitten with typedef'd arrays such as jmp_buf. I feel strongly that one should be able to take the address of an array with the address-of operator, for reasons of orthogonality--in other words, so that the bite would be a little less harsh. The issue came before the ANSI C committee this last meeting, and was voted down, so "&array" still doesn't work. The members seemed to feel that it was an extension, rather than the removal of an anomalous restriction. I have a pretty good justification for feeling otherwise, which I'll post at some point. Sam Kendall {allegra,ihnp4,ima,amd}!wjh12!kendall Delft Consulting Corp. decvax!genrad!wjh12!kendall
sdyer@bbncca.ARPA (Steve Dyer) (10/06/84)
When I first cut my teeth on C, in both the V6 and V7 Ritchie PDP-11 C compilers, &array was accepted as a valid construct, and one which had quite different semantics under pointer arithmetic from merely the array name alone: if we have char x[10]; x + 1 points to the second char in the array, equivalent to &x[1]. &x + 1 points to the memory address FOLLOWING the entire array, equivalent to &x[10]. That is, the size of the object pointed to is equal to the size of the entire array. Checking our present compiler, which is derived from the Ritchie PDP-11 V7 compiler, it behaves in this manner. -- /Steve Dyer {decvax,linus,ima,ihnp4}!bbncca!sdyer sdyer@bbncca.ARPA
bsa@ncoast.UUCP (Brandon Allbery) (10/07/84)
I think I have to clarify what I said in my last posting on this -- I didn't explain why the &array was a no-no. Forgive me if this is common knowledge. C purportedly handles arrays as if they were blocks of data and pointers. However, it doesn't, quite. The declaration char **foo, bar[10]; should allow me to say foo = &bar; later on.h, since bar should be a pointer to char. Unfortunately, bar is what I call a VIRTUAL pointer -- it assembles as a literal (look at your compiler's output). To work correctly, it would have to assemble to a constant pointer which always points to a particular block of memory, in which case the above would work. (Notice that the above is essentially the jmp_buf, expanded.) Instead, there is no such thing as &bar because bar is not a variable, it is a literal. One solution to this is to implement arrays as I showed above (in fact, I considered writing a C-like language which used something like char ch*5; /* a (char *) whose value is the address of a block of 5 characters */ but I don't think I can resolve possible conflicting uses of *); another is to treat the jmp_buf typedef as having an implicit struct definition, in which case the syntax jmp_buf *foo, bar; bar = &foo; would expand to struct __jmp_buf {char jmp_buf[10];} *foo, bar; bar = &foo; and since &struct is legal, it would work. I think typedef should do something like this, with `invisible' structs. Anyone see problems with it? (Probably; I've only been at this for a year. :-) --bsa
mann@CSL-Vax.ARPA (Tim Mann) (10/13/84)
> C purportedly handles arrays as if they were blocks of data and pointers. > However, it doesn't, quite. The declaration > > char **foo, bar[10]; > > should allow me to say > > foo = &bar; > > later on.h, since bar should be a pointer to char. Unfortunately, bar > is what I call a VIRTUAL pointer -- it assembles as a literal (look at > your compiler's output). To work correctly, it would have to assemble > to a constant pointer which always points to a particular block of memory, > in which case the above would work. (Notice that the above is essentially > the jmp_buf, expanded.) Instead, there is no such thing as &bar because > bar is not a variable, it is a literal. This is not an anomaly, and there is no reason to invent the term "virtual pointer". In your example, "bar" is a constant of type pointer-to-char. As a constant, it does not have an address. It is no more legitimate to write &bar and expect to get the address of a cell containing bar's value, than it would be to write &1 and expect to get the address of a cell with the value 1 in it. I'm not going to try to respond to the other points in your message or the other discussion that's been going on in this area just now. --Tim
stew@harvard.ARPA (Stew Rubenstein) (10/21/84)
> > C purportedly handles arrays as if they were blocks of data and pointers. > > However, it doesn't, quite. The declaration > > > > char **foo, bar[10]; > > > > should allow me to say > > > > foo = &bar; > > > > later on.h, since bar should be a pointer to char. Unfortunately, bar > > is what I call a VIRTUAL pointer -- it assembles as a literal (look at > > your compiler's output). To work correctly, it would have to assemble > > to a constant pointer which always points to a particular block of memory, > > in which case the above would work. (Notice that the above is essentially > > the jmp_buf, expanded.) Instead, there is no such thing as &bar because > > bar is not a variable, it is a literal. > > This is not an anomaly, and there is no reason to invent the term "virtual > pointer". In your example, "bar" is a constant of type pointer-to-char. As > a constant, it does not have an address. It is no more legitimate to write > &bar and expect to get the address of a cell containing bar's value, than it > would be to write &1 and expect to get the address of a cell with the value > 1 in it. > > I'm not going to try to respond to the other points in your message or the > other discussion that's been going on in this area just now. > > --Tim Ah, but Vax/VMS VAX-11 C *does* allow &1, meaning the address of a cell with a 1 in it. However, only for the special case of function call argument lists so that you can pass a constant by reference to languages that don't have call-by-value. -- ----------------------- Stew Rubenstein UUCP: ihnp4!harvard!stew Harvard Chemistry ARPA: stew@harvard