ok@cs.mu.oz.au (Richard O'Keefe) (10/10/89)
I have a program which uses a statically initialised array of function pointers (a couple of hundred of them). At the moment, the file which contains the array looks like ... extern void (*(dispatch[]))(); ... void foo() { ... (*dispatch[i])(); ... } ... void baz() { ... (*dispatch[j])(); ... } ... static void (*(dispatch[]))() = { ... foo, ..., baz, ... }; ... I want to make the program ANSI-conformation. GCC prints a warning about this; it doesn't like dispatch[] being extern and static both. Neither do I, but it was the only way I could talk another C compiler into accepting it. How should I organise this in ANSI C? I'd really rather _not_ add a couple of hundred function prototypes.
karl@haddock.ima.isc.com (Karl Heuer) (10/12/89)
In article <2364@munnari.oz.au> ok@cs.mu.oz.au (Richard O'Keefe) writes: > extern void (*(dispatch[]))(); > static void (*(dispatch[]))() = { ... foo, ..., baz, ... }; The ANSI way to do this is to use `static' rather than `extern' in the first declaration. This makes it a `tentative definition', which can be thought of as a kludge around the ambiguity between declarations and uninitialized definitions; it retroactively becomes a definition only if no real definition appears before the end of the translation unit. In this case, the initialized declaration later on would be the real definition, causing the earlier one to be treated as a forward declaration only. Unfortunately, not all existing pre-ANSI compilers agree with this. Even more unfortunately, some do not have *any* way to forward-declare a static object, so you can't just use `#if __STDC__ static #else extern #endif' and expect it to be portable. For full portability (without rearranging it to be a backward reference), you'd need to make the `dispatch' object global instead of static. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
ok@cs.mu.oz.au (Richard O'Keefe) (10/12/89)
In article <2364@munnari.oz.au> ok@cs.mu.oz.au (Richard O'Keefe) writes: > extern void (*(dispatch[]))(); > static void (*(dispatch[]))() = { ... foo, ..., baz, ... }; In article <14868@haddock.ima.isc.com>, karl@haddock.ima.isc.com (Karl Heuer) writes: : The ANSI way to do this is to use `static' rather than `extern' in the first : declaration. I received E-mail from two other people suggesting this. It's obvious enough, in all conscience, to make the two declarations agree about the storage class. The trouble is that the nearest thing to an ANSI compiler available to me is gcc 1.36, which doesn't like it. As the man says: : Unfortunately, not all existing pre-ANSI compilers agree with this. Oh well, I should have known I was asking for trouble when I had to use the extern/static hack to make the PDP-11 compiler happy way back when.