faustus@ic.Berkeley.EDU (Wayne A. Christopher) (07/01/88)
Is the following acceptable C code: extern int foo(); bar() { int (*bla)() = foo; /* CASE 1 */ foo(); /* CASE 2 */ } static int foo() { ... } In other words, should extern be interpreted as "possible forward reference" (the way I'm using it), or "externally defined symbol"? All the compilers I have used handle case 2 ok, but one couldn't deal with case 1. Shouldn't they both work the same? From an aesthetic viewpoint, I like to use extern anywhere I declare something but don't define it. I think writing int foo(); for static functions is not as clear. Wayne
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/02/88)
In article <4182@pasteur.Berkeley.Edu> faustus@ic.Berkeley.EDU (Wayne A. Christopher) writes: >Is the following acceptable C code: No. >From an aesthetic viewpoint, I like to use extern anywhere I declare >something but don't define it. I think writing > int foo(); >for static functions is not as clear. What you should have written was static int foo(); Aesthetics and proper use of the language have no necessary connection.
leo@philmds.UUCP (Leo de Wit) (07/02/88)
In article <4182@pasteur.Berkeley.Edu> faustus@ic.Berkeley.EDU (Wayne A. Christopher) writes: |Is the following acceptable C code: | | extern int foo(); | | bar() | { | int (*bla)() = foo; /* CASE 1 */ | | foo(); /* CASE 2 */ | } | | static int | foo() | { | ... | } | |In other words, should extern be interpreted as "possible forward |reference" (the way I'm using it), or "externally defined symbol"? All |the compilers I have used handle case 2 ok, but one couldn't deal with |case 1. Shouldn't they both work the same? | |From an aesthetic viewpoint, I like to use extern anywhere I declare |something but don't define it. I think writing | | int foo(); | |for static functions is not as clear. | | Wayne Indeed. You should write static int foo(); This is - in my point of view - the only correct forward declaration. It is also better from aesthetic point of view, in that it does use the correct storage type. Notably the Lattice C compiler is rather strict regarding storage classes / extern definitions; I like that. As for extern declarations, they typically belong in a header file (the one that belongs to the module defining the extern function / variable, i.e. is the - outgoing - interface of that module to the outside world). Leo (that's the way I C it; don't blame me for being stubborn 8-).
karzes@mfci.UUCP (Tom Karzes) (07/04/88)
In article <8200@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >What you should have written was > > static int foo(); > >Aesthetics and proper use of the language have no necessary connection. I've always found K&R to be very obscure on external declarations. Among other things, they don't explicitly say that static can be used for forward function declarations, although pcc-based C compilers have always allowed it, and it makes sense. However, I still consider static forwards to be broken in C. Sure, they work for functions, but what about data? For example, consider the following: struct foo { int a; struct bar *bar_ptr; }; struct bar { int b; struct foo *foo_ptr; }; extern struct foo x; extern struct bar y; struct foo x = {123, &y}; struct bar y = {456, &x}; Now suppose you want to make x and y static. What do you do? You still need a forward declaration for at least one of them in order to refer to it in an initialization list. Unless there's some way to do this that I don't know about, it's a glaring hole in C. Even if this case didn't matter, it would still be nice to be able to issue forward declarations for static data. Does anyone know if this has been fixed in ANSI C (e.g., by allowing something suitably gross like "extern static" as a forward declaration)?
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/05/88)
In article <457@m3.mfci.UUCP> karzes@mfci.UUCP (Tom Karzes) writes: > extern struct foo x; > extern struct bar y; > struct foo x = {123, &y}; > struct bar y = {456, &x}; >Now suppose you want to make x and y static. What do you do? Same thing, but include "static" in all declarations that mention them, particularly the first. static struct foo x; static struct bar y; static struct foo x = { 123, &y }; static struct bar y = { 456, &x };
karzes@mfci.UUCP (Tom Karzes) (07/06/88)
In article <8213@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: }Same thing, but include "static" in all declarations that mention }them, particularly the first. } } static struct foo x; } static struct bar y; } static struct foo x = { 123, &y }; } static struct bar y = { 456, &x }; That might work in ANSI C, but it isn't legal K&R C. In K&R C the second declarations of x and y constitute illegal redeclarartions, and with the compilers I've tried compilation fails with a user error.