[net.bugs.4bsd] Compiler bug

wolf@galbp.UUCP (Wolf Herda) (05/01/85)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***

I noticed this idiosyncrasy with regards to our C compiler.  Given the
following

>	int	a;
>	int	a;
>
>	main()
>	{
>		for (;;)
>			;
>	}

When compiling this, the compiler generates no error messages.  Seems
to me, it should give a "redeclaration of a" error message.  It does
give the error message, if the two int's are made automatic variables
(i.e., declared within main()).

Does anyone know why?  If it matters, this was done on a VAX 11/750
running 4.2BSD.
-- 

Wolf Herda
Lanier Business Products, Inc.
{gatech,akgua}!galbp!wolf
(404) 329-8254

jss@sjuvax.UUCP (J. Shapiro) (05/07/85)

I recently noticed that the following will not compile correctly on a
4.2 BSD system:

extern int usr1(), usr2(), usr3();

int	usrprocs[] = { usr1, usr2, usr3 }

whereas it compiles correctly on intel machines, cromix, and Aztec C.
It seems to me that this is something the linker should be able to handle
correctly, and therefore should not be a bug.

Comments?

Would someone be good enough to check this out on a sysV machine?

Jon

ed@mtxinu.UUCP (Ed Gould) (05/07/85)

> I noticed this idiosyncrasy with regards to our C compiler.  Given the
> following
> 
> >	int	a;
> >	int	a;
> >
> >	main()
> >	{
> >		for (;;)
> >			;
> >	}
> 
> When compiling this, the compiler generates no error messages.  Seems
> to me, it should give a "redeclaration of a" error message.  It does
> give the error message, if the two int's are made automatic variables
> (i.e., declared within main()).
> 
> ... running 4.2BSD.

The C language allows multiple definitions of *external* variables.
In all (that I know of, anyway) implementations under Unix declarations
made outside of a function are external - not just to the functions
in that file, but to the file as well.

Some AT&T compilers - specifically those on System V - complain about
the construction you describe.  Lots of folks have griped about that!
If the declarations *within* one file aren't consistent, e.g.,

	int a;
	struct {
	    int c;
	    int d;
	} a;

any compiler should complain.  (Of course, there is *no* checking
if the declarations are in separately-compiled files!)

-- 
Ed Gould		    mt Xinu, 2910 Seventh St., Berkeley, CA  94710  USA
{ucbvax,decvax}!mtxinu!ed   +1 415 644 0146

root@bu-cs.UUCP (Barry Shein) (05/08/85)

>From: jss@sjuvax.UUCP (J. Shapiro)
>I recently noticed that the following will not compile correctly on a
>4.2 BSD system:
>extern int usr1(), usr2(), usr3();
>int	usrprocs[] = { usr1, usr2, usr3 }
>...
Would someone be good enough to check this out on a sysV machine?
I believe it won't compile because it's wrong, try:

extern int usr1(), usr2(), usr3() ;
int (*usrprocs[])() = { usr1, usr2, usr3 } ;

ie. that isn't an array of ints, it's an array of pointers to
functions returning int (phew.) If other compilers aren't
complaining, they're being lazy and not doing their job.
Confusing ints with pointers is a classic port problem.

	-Barry Shein, Boston University

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (05/08/85)

> extern int usr1(), usr2(), usr3();
> 
> int	usrprocs[] = { usr1, usr2, usr3 }

There is no particular reason that this SHOULD work!  Try
	int	(*userprocs[])() = { usr1, usr2, usr3 };

jonab@sdcrdcf.UUCP (Jonathan Biggar) (05/08/85)

In article <1136@sjuvax.UUCP> jss@sjuvax.UUCP (J. Shapiro) writes:
>I recently noticed that the following will not compile correctly on a
>4.2 BSD system:
>
>extern int usr1(), usr2(), usr3();
>
>int	usrprocs[] = { usr1, usr2, usr3 }
>
>whereas it compiles correctly on intel machines, cromix, and Aztec C.
>It seems to me that this is something the linker should be able to handle
>correctly, and therefore should not be a bug.

It won't compile under 4.2bsd because the code is WRONG!  The array should
be declared as:

int	(*usrprocs[])() = { usr1, usr2, usr3 };

Jon Biggar
{allegra,burdvax,cbosgd,hplabs,ihnp4,sdccsu3}!sdcrdcf!jonab

martillo@mit-athena.UUCP (Joaquim Martillo) (05/09/85)

extern int usr1(), usr2(), usr3();

int usrprocs[] = { usr1, usr2, usr3 };

Should not compile (with compiler errors not liner errors) since you
have an illegal combination of pointers and integers.  The proper
way to do this is:

extern int usr1(), usr2(), usr3();

int (*(usrprocs[]))() = { usr1, usr2, usr3 };

which should be fairly obvious if you think about it.  There are of
course misimplementations of the C compiler floating around.

hans@log-hb.UUCP (Hans Albertsson) (05/09/85)

In article <1136@sjuvax.UUCP> jss@sjuvax.UUCP (J. Shapiro) writes:
>I recently noticed that the following will not compile correctly on a
>4.2 BSD system:
>
>extern int usr1(), usr2(), usr3();
>
>int	usrprocs[] = { usr1, usr2, usr3 }
>
>whereas it compiles correctly on intel machines, cromix, and Aztec C.
>It seems to me that this is something the linker should be able to handle
>correctly, and therefore should not be a bug.
>
>Comments?
>
>Would someone be good enough to check this out on a sysV machine?
>
>Jon


I don't think your declaration is quite correct; Shouldnt it have been

int (usrprocs[])() = { usr1, usr2, usr3 } ?

This declares an array of functions returning integer, which is what
the objects usrn might be considered to be, while your declaration says
array of integer.

Not even my version is quite correct. I ususally say

int ( *usrprocs[] )() = { usr1 ... 

to get the proper effect, since ( to quote K&R ) " if a function name 
appears in an expression, not in the position of a function call,
a pointer to the function is generated."
-- 
Hans Albertsson, USENET/uucp: {decvax,philabs}!mcvax!enea!log-hb!hans
Real World:  TeleLOGIC AB, Box 1001, S-14901 Nynashamn,SWEDEN

alan@drivax.UUCP (Alan Fargusson) (05/09/85)

> extern int usr1(), usr2(), usr3();
> 
> int	usrprocs[] = { usr1, usr2, usr3 }
> 
> Would someone be good enough to check this out on a sysV machine?

My SysV machine (VAX) gives me:
"bug.c", line 3: warning: illegal combination of pointer and integer, op =
"bug.c", line 3: warning: illegal combination of pointer and integer, op =
"bug.c", line 3: warning: illegal combination of pointer and integer, op =

This is what I would expect. What did BSD do?
-- 

Alan Fargusson.

{ ihnp4, sftig, amdahl, ucscc, ucbvax!unisoft }!drivax!alan

ed@mtxinu.UUCP (Ed Gould) (05/10/85)

> I recently noticed that the following will not compile correctly on a
> 4.2 BSD system:
> 
> extern int usr1(), usr2(), usr3();
> 
> int	usrprocs[] = { usr1, usr2, usr3 }
> 
> whereas it compiles correctly on intel machines, cromix, and Aztec C.
> It seems to me that this is something the linker should be able to handle
> correctly, and therefore should not be a bug.
> 
> Comments?
> 
> Would someone be good enough to check this out on a sysV machine?
> 
> Jon

It seems to me that the second declaration should be

	int	(*(usrprocs()))[] = { usr1, usr2, usr3 };
	/*      |          ||||
	 *      | |----------||
	 *      |-------------|
	 */

since usr[123] are, in this context, *pointers* to functions.
I couldnt get that to compile either, though.

-- 
Ed Gould		    mt Xinu, 2910 Seventh St., Berkeley, CA  94710  USA
{ucbvax,decvax}!mtxinu!ed   +1 415 644 0146

kanner@tymix.UUCP (Herb Kanner) (05/10/85)

In article <1136@sjuvax.UUCP> jss@sjuvax.UUCP (J. Shapiro) writes:
>I recently noticed that the following will not compile correctly on a
>4.2 BSD system:
>
>extern int usr1(), usr2(), usr3();
>
>int	usrprocs[] = { usr1, usr2, usr3 }
>
>whereas it compiles correctly on intel machines, cromix, and Aztec C.
>It seems to me that this is something the linker should be able to handle
>correctly, and therefore should not be a bug.
>
You want to use

extern int usr1(), usr2(), usr3();

int (*usrprocs[])() = { usr1, usr2, usr3 };

The call is written as (*usrprocs[i])() and can even have parameters, e.g.
(*usrprocs[i])(a, b, c) provided the number and types of the parameters are
identical for all three functions.


-- 
Herb Kanner
Tymnet, Inc.

guy@sun.uucp (Guy Harris) (05/18/85)

> > extern int usr1(), usr2(), usr3();
> > 
> > int	usrprocs[] = { usr1, usr2, usr3 }
> > 
> > Would someone be good enough to check this out on a sysV machine?
> 
> My SysV machine (VAX) gives me:
> "bug.c", line 3: warning: illegal combination of pointer and integer, op =
> "bug.c", line 3: warning: illegal combination of pointer and integer, op =
> "bug.c", line 3: warning: illegal combination of pointer and integer, op =
> 
> This is what I would expect. What did BSD do?

The same thing (although my 4.2BSD machine is a Sun, I think it does the
same thing on a VAX; the 4.2BSD VAX compiler is basically the SysIII
compiler).  *Everybody* should expect it.  The above code is simply wrong.
If your compiler doesn't complain, complain to the author(s) of your
compiler.  "Type-correctness is everybody's business."

	Guy Harris