timd@ur-tut.UUCP (Tim D'Ascoli) (08/18/86)
I hope that this posting will help someone avoid the "extra" debug time that i had to spend when i was using Consulair's Mac C compiler. In The Bible (K & R) on page 94 the following quote can be found, "In short, any array and index expression can be written as a pointer and offset, and vice versa, even in the same statement.", (5:3:6 -- chapter, verse, and paragraph). My problem came with the following code segment: /* declared as a global variable */ char **inputBuffer; /* and then subsequently referenced in another file */ extern char *inputBuffer[]; /* the following variable was also declared in that file ** as a local */ char *inputArray; /* and then de-referencing the global in that file */ inputArray = *inputBuffer; Where this inputArray variable pointed to was not where i had intended, and when i investigated further i found that when the global variable is declared as it was above (extern char *inputBuffer[];) the de-referencing generates a LEA.L (load effective address) call. However, when the extern declaration is done using the "star star" format (i.e. extern char **inputBuffer;), and the de-reference line left unchanged, the code generated is a MOVEA.L (move effective address) which gave me what i had expected from the de-referencing in the first place. Another interesting fact about the Consulair Mac C compiler is that it generates self modifying code (that may not make a migration to a 68020 machine). I found this when i used some of the PBxxxx() calls for file i/o. (The location of the trap is AND'ed with a constant to produce the desired PB trap call). posted in an effort to help. - timd
radford@calgary.UUCP (Radford Neal) (08/21/86)
In article <605@ur-tut.UUCP>, timd@ur-tut.UUCP (Tim D'Ascoli) writes: > I hope that this posting will help someone avoid the "extra" debug time > that i had to spend when i was using Consulair's Mac C compiler. > In The Bible (K & R) on page 94 the following quote can be found, > "In short, any array and index expression can be written as a pointer and > offset, and vice versa, even in the same statement.", > (5:3:6 -- chapter, verse, and paragraph). > > My problem came with the following code segment: > > /* declared as a global variable */ > char **inputBuffer; > > /* and then subsequently referenced in another file */ > extern char *inputBuffer[]; > > /* the following variable was also declared in that file > ** as a local > */ > char *inputArray; > > /* and then de-referencing the global in that file */ > inputArray = *inputBuffer; I wouldn't consider this a flaw in Consulair C. I would expect this code to be broken on any C compiler. Your declaration char *inputBuffer[]; will expect to link to an actual allocated array of pointers to characters, not to a pointer to a pointer. This is just the way C is. K&R may have explained it poorly, but that's not Consulair's fault. Radford Neal The University of Calgary
tim@ism780c.UUCP (Tim Smith) (08/22/86)
Consulair is correct here. When something is declared as extern char *FOO[]; then FOO is an external constant ( the address of an array whose elements are of type (char *) ). If the place that allocates storage for FOO uses char **FOO; then FOO is now a variable that holds a pointer to something of type (char *). Thus, there is one more level of indirection. Note that the cited reference in The Book is talking about stuff in expressions. You can use either [] notation or * notation to dereference things, just like The Holy Ones say, in expressions. However, declarations are not expressions. You must declare the variable the same way in both places for things to work. On Unix, this often screws up people who use sys_errlist to print error messages. It is declared as char *sys_errlist[]; in the header file, and people often put char **sys_errlist; in their programs, leading to a quick coredump the first time they try to use it. -- "I *DO* believe in Mary Worth" Tim Smith USENET: sdcrdcf!ism780c!tim || ima!ism780!tim Compuserve: 72257,3706 Delphi || GEnie: mnementh