nazgul@apollo.uucp (Kee Hinckley) (10/04/84)
...let's hear it for cut and paste... > "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. Either your C compiler > has a bug in this respect, or your <setjmp.h> is #defining jmp_buf, instead of > typedefing it. The thing to do is not gripe about the language, but gripe to > whomever maintains your compiler, to get this bug fixed. > -- > Morris M. Keesan > {decvax,linus,ihnp4,wivax,wjh12,ima}!bbncca!keesan > keesan @ BBN-UNIX.ARPA Consider the following: char c[10], *cptr; cptr = c; Clearly "c", without any subscripts is equivlent to "*cptr", I've yet to see a C compiler complain about THAT line. This means that "c" is a "pointer to character", NOT a pointer to an array of characters. Therefore taking its address is equivilent to "&cptr", or asking for the address of the actual pointer. Conceptually, "typedef" ought (my definition of ought) make the type into an abstract object, which no longer depends upon the fact that it used to be an array. In fact it does not, and thus: typedef char jmp_buf[10]; jmp_buf c, *cptr; cptr = &c; ends up being incorrect. Now, just in case you think my compiler is strange (Apollo CC). Here is the Berkeley 4.2 example. %8% cat foo.c typedef char jmp_buf[10]; main() { jmp_buf c, *cptr; cptr = c; cptr = &c; cptr = (jmp_buf *) &c; cptr = (jmp_buf *) c; } %9% cc foo.c "foo.c", line 6: warning: illegal pointer combination "foo.c", line 7: warning: & before array or function: ignored "foo.c", line 7: warning: illegal pointer combination "foo.c", line 8: warning: & before array or function: ignored %10% ---------------------- Apollo CC ---------------------- -=> catf foo.c typedef char jmp_buf[10]; main() { jmp_buf c, *cptr; cptr = c; cptr = &c; cptr = (jmp_buf *) &c; cptr = (jmp_buf *) c; } -=> cc foo.c (0006) cptr = c; ******** Line 6: Warning: Illegal pointer combination: incompatible types. (0007) cptr = &c; ******** Line 7: Warning: Illegal pointer combination: incompatible types. No errors, 2 warnings, C Compiler, Rev 2.40 -------------------------------------------------- Now I'm not saying that Berkeley has the right error messages either, in particular the complaints about the '&'s are completely out of place given that typedef is *supposed* to make things more data independant. I might note however, that our version of PCC also complains about incompatable types (although not the '&'). What's the correct answer? I don't know. Probably the best thing to do is avoid typedef'ing arrays completely. -kee ...decvax!wivax!apollo!nazgul
martillo@mit-athena.ARPA (Joaquim Martillo) (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. Either your C compiler >> has a bug in this respect, or your <setjmp.h> is #defining jmp_buf, instead of >> typedefing it. The thing to do is not gripe about the language, but gripe to >> whomever maintains your compiler, to get this bug fixed. >> -- >> Morris M. Keesan >> {decvax,linus,ihnp4,wivax,wjh12,ima}!bbncca!keesan >> keesan @ BBN-UNIX.ARPA > >Consider the following: > char c[10], *cptr; > > cptr = c; > > Clearly "c", without any subscripts is equivlent to "*cptr", I've yet to >see a C compiler complain about THAT line. This means that "c" is a "pointer >to character", NOT a pointer to an array of characters. Therefore taking >its address is equivilent to "&cptr", or asking for the address of the actual >pointer. > Conceptually, "typedef" ought (my definition of ought) make the type into >an abstract object, which no longer depends upon the fact that it used to be an >array. In fact it does not, and thus: > > typedef char jmp_buf[10]; > jmp_buf c, *cptr; > > cptr = &c; > >ends up being incorrect. > >Now, just in case you think my compiler is strange (Apollo CC). Here is >the Berkeley 4.2 example. > > %8% cat foo.c > typedef char jmp_buf[10]; > main() > { > jmp_buf c, *cptr; > > cptr = c; > cptr = &c; > cptr = (jmp_buf *) &c; > cptr = (jmp_buf *) c; > } > %9% cc foo.c > "foo.c", line 6: warning: illegal pointer combination > "foo.c", line 7: warning: & before array or function: ignored > "foo.c", line 7: warning: illegal pointer combination > "foo.c", line 8: warning: & before array or function: ignored > %10% >---------------------- >Apollo CC >---------------------- >-=> catf foo.c > typedef char jmp_buf[10]; > main() > { > jmp_buf c, *cptr; > > cptr = c; > cptr = &c; > cptr = (jmp_buf *) &c; > cptr = (jmp_buf *) c; > } >-=> cc foo.c > > (0006) cptr = c; >******** Line 6: Warning: Illegal pointer combination: incompatible types. > > (0007) cptr = &c; >******** Line 7: Warning: Illegal pointer combination: incompatible types. >No errors, 2 warnings, C Compiler, Rev 2.40 > >-------------------------------------------------- >Now I'm not saying that Berkeley has the right error messages either, >in particular the complaints about the '&'s are completely out of place >given that typedef is *supposed* to make things more data independant. >I might note however, that our version of PCC also complains about >incompatable types (although not the '&'). > >What's the correct answer? I don't know. Probably the best thing to do >is avoid typedef'ing arrays completely. > > > -kee > ...decvax!wivax!apollo!nazgul > > > Apollo is correct and Berkeley is wrong at least as I understand how C compilers work at ATT. A jmp_buf is not exactly an array. It is a fixed length, array, i. e. a block of memory of known size a.k.a structure. Thus at ATT if new_jmp_buf and old_jmp_buf are defined as jmp_buf's jmp_buf new_jmp_buf, old_jmp_buf; .......... /* Fill up old_jmp_buf */ .......... new_jmp_buf = old_jmp_buf; works (or should work). Therefore, just as struct tag node, *p = &node; works so should jmp_buf save, *p = &save; also work.
martillo@mit-athena.ARPA (Joaquim Martillo) (10/05/84)
Sorry, rereading the article, I realize both Berkeley and Apollo are wrong and that ATT is correct.
chris@umcp-cs.UUCP (Chris Torek) (10/06/84)
One can always (sigh) cheat and write
typedef struct {
int a[10];
} jmp_buf;
There is an obvious problem with changing the language such that
typedef int foo[10];
makes ``foo'' a type which is considered a unit (like structs and
unions and basic types), and that is that it would probably break
quite a bit of existing code.
--
(This mind accidently left blank.)
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@maryland
guy@rlgvax.UUCP (Guy Harris) (10/06/84)
>...> Discussion of "jmp_buf" typedefed as an array causing various >...> compilation errors. > > Apollo is correct and Berkeley is wrong at least as I understand how C > compilers work at ATT. A jmp_buf is not exactly an array. It is a > fixed length, array, i. e. a block of memory of known size a.k.a > structure. Not as of System V Release 2; it's still an array, not a structure, in the include file "setjmp.h". Thus, the example you give later of structure copying between "jmp_buf"s won't work either. Maybe some non-mainstream versions of UNIX have defined it as a structure (it probably should be so defined, 1) because it doesn't do any harm, 2) because structures, unlike arrays, can be dealt with in a semi-abstract fashion and won't cause problems when you stick an "&" in front of one's name, and 3) because that way you can put mnemonic names on the elements of the jmp_buf, so you can figure out "OK, it sticks the current frame pointer in the fifth word"). Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
geoff@desint.UUCP (Geoff Kuenning) (10/06/84)
>What's the correct answer? I don't know. Probably the best thing to do >is avoid typedef'ing arrays completely. > Kee Hinckley Amen! Note that if the guy who typedef'ed jmp_buf had made it a struct, not only would it have been more flexible, but the construct under discussion ("jmp_buf c, *cp; cp = &c;") would have been perfectly legal. Now, of course, there are thousands of people out there who have been forced to write code that assumes jmp_buf is an array, so fixing the typedef to be a struct like it should have in the first place will break all that code. *SIGH*. (I was never too happy with the idea of typedef'ing something as a fixed-size array, anyway. Doesn't sit well with my hick notions of what a typedef out to be.) -- Geoff Kuenning First Systems Corporation ...!ihnp4!trwrb!desint!geoff
warren@tikal.UUCP (warren) (10/10/84)
[There are no bugs] It seems to me that typedef'ing something to an array uncovers some ambiguity in the C language, in that array names are constants, not variables. Typedef'ing to a constant is rather odd to begin with. One feels it perhaps ought to be illegal. Or at least very rude. For example, would you accept "typedef 7 foo;" ? Array names are "pointer constants" of the type of "pointer to the first element of the array". Other languages and machines used to call this sort of thing an "address constant". Of course, there is an inconsistancy. The "sizeof(arrayname)" expression is the number of bytes in all the elements of the array. Furthermore, when an arrayname is passed as the actual argument to a function, the formal function argument (in the function) has some other size entirely. On machines that do not address a byte directly, the number of bytes in array of pointers or of floating point constants does not even have to be an integer ! teltone!warren