phrrngtn@cs.tcd.ie (Paul Harrington) (10/14/88)
(I tried posting this before but it did not arrive) The following code was tested on a SUN 3/50 under SunOS 3.3. Depending on wheter you give an initialiser to the enum elements in the declaration of the type of p or not you get very different outputs from test_fn() ranging from 1,3,5 to 1,2,4 to 2,4,6 with my old favourite 2,3,4 when you say a=1,b=2,c=3 in the declaration of the type of p in test_fn() An RPC package called Courier generates this unusual type of code with parameter types being redeclared even for functions that have the same effective types for their parameters. why does the compiler (I don't know which compiler it is. I assume it is the standard one supplied with a SUN 3/50) produce this result and is it a bug of this compiler or a "feature" of C ? typedef struct { enum{a=1,b,c}choice; union{ int a; long b; short c; }u; }new_struct; typedef enum {e,f,g,h} e1; void test_fn1(p) struct { enum{a=1,b=2,c=3}choice; union{ int a; long b; short c; }u; }*p; { printf("the size of p is %d\n",sizeof(p)); printf("(test_fn1) a=%d,b=%d,c=%d\n",a,b,c); } main() { new_struct *v; printf("(main) a=%d,b=%d,c=%d\n",a,b,c); printf("the size of e1 is %d\n",sizeof(e1)); printf("the size of a is %d\n",sizeof(a)); test_fn1(v); }
guy@auspex.UUCP (Guy Harris) (10/19/88)
>why does the compiler (I don't know which compiler it is. I assume it is >the standard one supplied with a SUN 3/50) ...which is based on PCC or its descendants, like many (most?) UNIX C compilers, so I suspect this bug may exist in other UNIX C compilers as well... >produce this result and is it a bug of this compiler or a "feature" of C ? According to K&R, second edition (which includes stuff from a recent ANSI C draft): Enumerator names in the same scope must all be distinct from each other and from ordinary variable names, but the values need not be distinct. I infer from K&R 2 that the scope of the "enum" in "new_struct" is the entire source file and the scope of the "enum" in "*p" to be the function "test_fn1". Now, K&R 2 also says If an identifier is explicitly declared at the head of a block, including the block constituting a function, any declaration of the identifier ouside the block is suspended until the end of the block. From that, I infer that the declaration "a", "b",and "c" in the definition of "new_struct" should be suspended inside the block constituting "test_fn1", so that this is a compiler bug.
chris@mimsy.UUCP (Chris Torek) (10/19/88)
In article <20@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >... From that, I infer that the declaration "a", "b",and "c" in the >definition of "new_struct" should be suspended inside the block >constituting "test_fn1", so that this is a compiler bug. It is quite definitely a compiler bug. Anything that causes a, b, and c to have the values 2, 3, and 4 when the most recent `enum' declaration read `enum { a=1, b, c }' is clearly a bug! I even know just where, but not precisely what to do to fix it. In mip/pftn.c we find the routine `defid', which, for a `MOE' (Member Of Enum) type, has the following code: if( scl == class ){ if( p->offset!= strucoff++ ) break; psave( idp ); } break; What happens is that `strucoff' (which keeps track of the offset of members of structures---enum type declarations are fudged as structures inside pcc) is incremented *twice*, once here (where it checks for a mismatch and may or may not allow the redeclaration, depending on whether this hides a previous declaration) and once below. I *think* that it should return after calling psave(), except that I am not sure that, if p->offset != strucoff++, strucoff should have been incremented. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
chris@mimsy.UUCP (Chris Torek) (10/20/88)
In article <14065@mimsy.UUCP> I noted that the bug was in the following few lines from src/lib/mip/pftn.c: > if( scl == class ){ > if( p->offset!= strucoff++ ) break; > psave( idp ); > } > break; but then added >... I *think* that it should return after calling psave(), except that >I am not sure that, if p->offset != strucoff++, strucoff should have >been incremented. Of course not! The code should read if( scl == class && p->offset == strucoff ){ strucoff++; psave( idp ); return; } break; -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris