home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.editors:1857 comp.lang.c:11795
- Path: sparky!uunet!olivea!sgigate!odin!mips!swrinde!gatech!concert!mcnc!aurs01!throop
- From: throop@aurs01.UUCP (Wayne Throop)
- Newsgroups: comp.editors,comp.lang.c
- Subject: Re: Editor mined (pointer declaration snafu)
- Message-ID: <60989@aurs01.UUCP>
- Date: 30 Jul 92 20:43:17 GMT
- References: <42I54HD@math.fu-berlin.de> <id.SWWR.HZI@ferranti.com> <86K51ZK@math.fu-berlin.de>
- Sender: news@aurs01.UUCP
- Followup-To: comp.lang.c
- Lines: 107
-
- Note that followups are set to comp.lang.c, as this discussion
- has reached a point at least partially covered in the C FAQ.
-
- > From: wolff@inf.fu-berlin.de (Thomas Wolff)
- > Message-ID: <86K51ZK@math.fu-berlin.de>
- > Mined runs fine on SunOS, Micro-Vax Ultrix, Iris IRIX, VMS, and MSDOS
- > including the following assignment [...] and its later uses:
- > char * (* fnamv) [];
- > ...
- > char * argv [];
- > fnamv = argv; /* Why does this produce a warning?
- > C is such a stupid language! */
-
- But even in (say) Pascal, the above would be illegal, so I don't see
- how C as a language is to blame. The equivalent Pascal would be
- (pardon my rusty pascalish... I may be mixing up pascal with
- some other pascalish language here) something like
-
- argv: array of pointer to char
- fnamv: pointer to array of pointer to char
- [...]
- fnamv := argv
-
- and would fail just as the C version does (though, interestingly
- enough, for subtly different reasons, given below).
-
- > I really don't think it's my fault that compilers produce warnings like
- > "illegal pointer combination" on this.
-
- But it *is* an illegal pointer combination. C compilers *should*
- complain at illegal pointer combinations like this. This is an attempt
- to assign a (char**) to a (char*(*)[]). In english, an attempt to
- assign a "pointer to pointers to chars" to a "pointer to arrays of
- unknown size of pointers to chars".
-
- ( Extra points for those who know why I said "pointer to pointers
- to chars" instead of "pointer to pointer to char" for (char**). )
-
- ( Note that argv has type (char*[]), but of course in a value
- context, array typed expressions like these yield a pointer to the
- first element of the array, and hence result in type (char**). )
-
- > If you could advise me how to change the declarations such that the
- > compiler does not complain AND it works, I would be thankful.
-
- First is the problem that some important context must have been left
- out, because the declaration
-
- char * argv[];
-
- can only be made legal if it's an extern, or a formal parameter
- declaration, or if you give it a size. Consider the following
- three functions, which show the original incorrect code fragment
- and three ways to fix it:
-
- void f1( void ){
- char *(*fnamv)[];
- char *argv[];
- fnamv = argv;
- }
- void f2( void ){
- char *(*fnamv)[10];
- char *argv[10];
- fnamv = &argv;
- }
- void f3( char *argv[] ){
- char **fnamv;
- fnamv = argv;
- }
- void f4( void ){
- char *(*fnamv)[];
- extern char *argv[];
- fnamv = &argv;
- }
-
- Using the command line gcc -c -ansi -pedantic -Wall,
- we have these error messages:
-
- In function f1:
- 3: array size missing in `argv'
- 4: warning: assignment between incompatible pointer types
-
- So the first thing is to make the declaration of argv legal. There
- are three ways to do that, demonstrated in f2, f3, and f4.
-
- In f2, argv is given a definite size. In this case, argv then
- has type (char*[10]), so to be type-correct, the address of
- argv needs to be assigned, because fnamv is of type (char*(*)[10]),
- that is, a pointer to the type of the argv object.
-
- In f3, argv has been made legal by being declared as a formal
- parameter. This means that argv has type (char**). Thus, to
- be type correct, fnamv must have its type corrected to match.
-
- In f4, argv has been made external. This has essentially the
- same properties as the solution in f2, but the fnamv declaration
- can also involve array of unknown size.
-
- Of the three solutions, the one in f3 is probably most appropriate.
-
- The reason that the illegal assignment of a (char**) to a (char*(*)[])
- works in many environments, is a consequence of the fact that
- subscripting is equivalent to an indirection of the sum of two
- expressions in C. This means that a pointer to the initial element of
- an
-
- Wayne Throop ...!mcnc!aurgate!throop
-