This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: c++/2478: false g++ error: incompatible types in assignment of `int* (*)[]' to `int *[0]'


The following reply was made to PR c++/2478; it has been noted by GNATS.

From: "Dave Korn" <davek-ml@ntlworld.com>
To: "Kenneth Gole" <kengole@us.ibm.com>,
	<gcc-gnats@gcc.gnu.org>,
	"gcc" <gcc@gcc.gnu.org>
Cc: "Don Pearl" <pearldl@us.ibm.com>
Subject: Re: c++/2478: false g++ error: incompatible types in assignment of `int* (*)[]' to `int *[0]'
Date: Sun, 8 Apr 2001 23:35:28 +0100

 ----- Original Message -----
 From: "Kenneth Gole" <kengole@us.ibm.com>
 Sent: Wednesday, April 04, 2001 6:30 PM
 
     Hi Ken,
 
   I've spent some time looking into this problem, and you have found a bug
 (or perhaps 'feature') in 2.95.3's C++ parser.
 
 > If I simplify my example to look like this:
 > --------------------------------------------------------------------------
 > /* A demonstration of a gcc 2.95.3 problem - KenGole@us.ibm.com */
    [Example snipped - see t2.C below]
 
   Ok: this isn't the same as the example in your original mail, I guess you
 retyped it rather than cut and paste it.  Here is what you actually sent in
 your first mail, and the result of compiling it:
 
 8<-------------------------------
 dkadmin@UBIK ~/test/gnat
 $ cat t1.C
 /* A demonstration of a gcc 2.95.3 problem - KenGole@us.ibm.com
 <mailto:KenGole@
 us.ibm.com> */
 #include <stdio.h>
 
 int main(void)
 {
 int *(*ArryPtr)[]=NULL; /* A pointer to an array of pointers */
 int *(*p)[]; /* Same type as ArryPtr */
 struct myStruct
 {
   int *(p)[]; /* Same type as ArryPtr */
 } B;
   p=ArryPtr; /* This compiles fine... */
   B.p=ArryPtr; /* This fails to compile! */
   return 0;
 }
 
 dkadmin@UBIK ~/test/gnat
 $ gcc t1.C -o t1
 t1.C: In function `int main()':
 t1.C:13: incompatible types in assignment of `int * (*)[]' to `int *[0]'
 8<-------------------------------
 
   Please note that you probably meant to have an asterisk inside the
 brackets around 'p' in the declaration of struct myStruct.  With that
 omission, p is an array of unknown size, which in a struct is the same thing
 as an array of zero length, of pointers-to-ints.  The square braces bind (p)
 with higher priority than the *.  Thus p is an actual zero length array of
 (int *), and the pointer ArryPtr that you are trying to assign to it is a
 pointer to an array of unknown size of (int *).  p is not a pointer, and the
 error message is correct.  Note that zero-length array fields in structs are
 a Gnu C extension.  In standard C this would be treated as an incomplete
 type.
 
   In the simplified (and corrected) example you sent me, you had replaced
 the asterisk inside the brackets, and hence p was indeed a pointer rather
 than an array:
 
 8<-------------------------------
 dkadmin@UBIK ~/test/gnat
 $ cat t2.C
 /* A demonstration of a gcc 2.95.3 problem - KenGole@us.ibm.com
 <mailto:KenGole@
 us.ibm.com> */
 #include <stdio.h>
 
 int main(void)
 {
 int (*ArryPtr)[]=NULL; /* A pointer to an array of integers */
 int (*q)[]; /* Same type as ArryPtr */
 struct myStruct
 {
   int (*p)[]; /* Same type as ArryPtr */
 } B;
   q=ArryPtr; /* This compiles fine... */
   B.p=ArryPtr; /* This fails to compile! */
   return 0;
 }
 
 dkadmin@UBIK ~/test/gnat
 $ gcc t2.C -o t2
 t2.C: In function `int main()':
 t2.C:13: assignment to `int (*)[0]' from `int (*)[]'
 8<-------------------------------
 
   And this is genuinely unexpected, and incorrect: p is not a pointer to a
 zero length array, but to an array of unknown length.  The parser is perhaps
 confused by the struct context, and thinks because we are in a struct (where
 an unsized array would be zero length) that this pointer is to a zero length
 rather than unsized array.  Interestingly enough, the bug does not occur
 when we compile the example in C:
 
 8<-------------------------------
 dkadmin@UBIK ~/test/gnat
 $ mv t2.C t2.c
 
 dkadmin@UBIK ~/test/gnat
 $ gcc t2.c -o t2
 
 dkadmin@UBIK ~/test/gnat
 $
 8<-------------------------------
 
   So you have indeed stumbled across a bug in the C++ parser.  It is
 misinterpreting the empty square braces as indicating a zero-sized, rather
 than unknown sized array; hence the error message.  This is because of the
 following piece of code in gcc-2.95.3/gcc/cp/decl.c, at lines 10381+
 
 8<-------------------------------
      /* VC++ spells a zero-sized array with [].  */
      if (size == NULL_TREE && decl_context == FIELD && ! staticp
   && ! RIDBIT_SETP (RID_TYPEDEF, specbits))
        size = integer_zero_node;
 8<-------------------------------
 
   It's clearly been put in as an aid to source compatibility with VC++.  If
 you remove these lines, your program will be parsed correctly.  I'm not sure
 if this is the ideal solution, however; I'm not enough of a parsing expert
 to be sure this patch won't have unforeseen complications.  I'm crossposting
 this message to the main gcc list because I think I remember a conversation
 here a couple of months back about this very subject in the 3.0 tree.
 
   Removing these lines has the following effects on compiling the two tests
 above:
 
 8<-------------------------------
 dkadmin@UBIK ~/test/gnat
 $ ~/prerelease/2953/gcc/xgcc.exe -B ~/prerelease/2953/gcc/ t1.C -o t1b
 t1.C: In function `int main()':
 t1.C:10: field `p' has incomplete type
 t1.C:11: confused by earlier errors, bailing out
 
 dkadmin@UBIK ~/test/gnat
 $ ~/prerelease/2953/gcc/xgcc.exe -B ~/prerelease/2953/gcc/ t2.C -o t2b
 
 dkadmin@UBIK ~/test/gnat
 $
 8<-------------------------------
 
 so I guess you've lost the Gnu C zero-length-array-in-a-struct extension,
 but you get back your proper compatibility.
 
   Can anyone on the main list suggest a better solution ?
 
           DaveK
 
 
 
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]