home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / editors / 1857 < prev    next >
Encoding:
Text File  |  1992-07-30  |  4.3 KB  |  120 lines

  1. Xref: sparky comp.editors:1857 comp.lang.c:11795
  2. Path: sparky!uunet!olivea!sgigate!odin!mips!swrinde!gatech!concert!mcnc!aurs01!throop
  3. From: throop@aurs01.UUCP (Wayne Throop)
  4. Newsgroups: comp.editors,comp.lang.c
  5. Subject: Re: Editor mined (pointer declaration snafu)
  6. Message-ID: <60989@aurs01.UUCP>
  7. Date: 30 Jul 92 20:43:17 GMT
  8. References: <42I54HD@math.fu-berlin.de> <id.SWWR.HZI@ferranti.com> <86K51ZK@math.fu-berlin.de>
  9. Sender: news@aurs01.UUCP
  10. Followup-To: comp.lang.c
  11. Lines: 107
  12.  
  13. Note that followups are set to comp.lang.c, as this discussion
  14. has reached a point at least partially covered in the C FAQ.
  15.  
  16. > From: wolff@inf.fu-berlin.de (Thomas Wolff)
  17. > Message-ID: <86K51ZK@math.fu-berlin.de>
  18. > Mined runs fine on SunOS, Micro-Vax Ultrix, Iris IRIX, VMS, and MSDOS
  19. > including the following assignment [...] and its later uses:
  20. >    char * (* fnamv) [];
  21. >      ...
  22. >      char * argv [];
  23. >      fnamv = argv; /* Why does this produce a warning? 
  24. >                       C is such a stupid language!  */
  25.  
  26. But even in (say) Pascal, the above would be illegal, so I don't see
  27. how C as a language is to blame.  The equivalent Pascal would be
  28. (pardon my rusty pascalish... I may be mixing up pascal with
  29. some other pascalish language here) something like
  30.  
  31.          argv: array of pointer to char
  32.          fnamv: pointer to array of pointer to char
  33.          [...]
  34.          fnamv := argv
  35.  
  36. and would fail just as the C version does (though, interestingly
  37. enough, for subtly different reasons, given below).
  38.  
  39. > I really don't think it's my fault that compilers produce warnings like
  40. > "illegal pointer combination" on this.
  41.  
  42. But it *is* an illegal pointer combination.   C compilers *should*
  43. complain at illegal pointer combinations like this.  This is an attempt
  44. to assign a (char**) to a (char*(*)[]).  In english, an attempt to
  45. assign a "pointer to pointers to chars"  to a "pointer to arrays of
  46. unknown size of pointers to chars".
  47.  
  48. ( Extra points for those who know why I said "pointer to pointers
  49.   to chars" instead of "pointer to pointer to char" for (char**). )
  50.  
  51. ( Note that argv has type (char*[]), but of course in a value
  52.   context, array typed expressions like these yield a pointer to the
  53.   first element of the array, and hence result in type (char**). )
  54.  
  55. > If you could advise me how to change the declarations such that the
  56. > compiler does not complain AND it works, I would be thankful.
  57.  
  58. First is the problem that some important context must have been left
  59. out, because the declaration
  60.  
  61.          char * argv[];
  62.  
  63. can only be made legal if it's an extern, or a formal parameter
  64. declaration, or if you give it a size.  Consider the following
  65. three functions, which show the original incorrect code fragment
  66. and three ways to fix it:
  67.  
  68.     void f1( void ){
  69.       char *(*fnamv)[];
  70.       char *argv[];
  71.       fnamv = argv; 
  72.     }
  73.     void f2( void ){
  74.       char *(*fnamv)[10];
  75.       char *argv[10];
  76.       fnamv = &argv; 
  77.     }
  78.     void f3( char *argv[] ){
  79.       char **fnamv;
  80.       fnamv = argv; 
  81.     }
  82.     void f4( void ){
  83.     char *(*fnamv)[];
  84.     extern char *argv[];
  85.     fnamv = &argv;
  86.     }
  87.  
  88. Using the command line    gcc -c -ansi -pedantic -Wall,
  89. we have these error messages:
  90.  
  91.       In function f1:
  92.      3: array size missing in `argv'
  93.      4: warning: assignment between incompatible pointer types
  94.  
  95. So the first thing is to make the declaration of argv legal.  There
  96. are three ways to do that, demonstrated in f2, f3, and f4.
  97.  
  98. In f2, argv is given a definite size.  In this case, argv then
  99. has type (char*[10]), so to be type-correct, the address of
  100. argv needs to be assigned, because fnamv is of type (char*(*)[10]),
  101. that is, a pointer to the type of the argv object.
  102.  
  103. In f3, argv has been made legal by being declared as a formal
  104. parameter.  This means that argv has type (char**).  Thus, to
  105. be type correct, fnamv must have its type corrected to match.
  106.  
  107. In f4, argv has been made external.  This has essentially the
  108. same properties as the solution in f2, but the fnamv declaration
  109. can also involve array of unknown size.
  110.  
  111. Of the three solutions, the one in f3 is probably most appropriate.
  112.  
  113. The reason that the illegal assignment of a (char**) to a (char*(*)[])
  114. works in many environments, is a consequence of the fact that
  115. subscripting is equivalent to an indirection of the sum of two
  116. expressions in C.  This means that a pointer to the initial element of
  117. an 
  118.  
  119. Wayne Throop       ...!mcnc!aurgate!throop
  120.