On Mon, Feb 18, 2013 at 9:38 AM, Charles Forsyth <charles.forsyth@gmail.com> wrote:
On 18 February 2013 13:02, Comeau At9Fans <comeauat9fans@gmail.com> wrote:
seems to be doing is setting up allowing the call to compile and once that is satisfied then the subsequent definition "has" to match it, as perhaps a way to do type punning.

No, the compiler is simply applying scope rules. Without that inner declaration explicitly overriding the outer declaration--whether static or extern is used--
it will not compile (eg, if you put "static void fn(Outer*);" or "extern void fn(Outer*);" and remove static from fn in the file scope).

The behaviour is undefined in ANSI C if two declarations that refer to the same object or function do not have compatible types
(normally, you're protected by another rule that you can't have incompatible declarations *in the same scope*).

ANSI C does, however, forbid the inner static declaration (which surprised me)
"The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern." (6.7.1)
 
We're probably saying the same thing.  As you say ANSI C forbids it hence my comment about normally a diagnostic from a so-called mainstream compiler.   And as you say without a declaration it would not compile either.  The declaration should normally be in global scope (it could have been), which would have also produced a diagnostic since Inner/Outer don't match.  That leaves the declaration where Eric showed it, which the Plan 9 compiler obviously allowed.  As you note the net effect is it's undefined (if we're using ANSI C as the metric) hence created a kind of type pun (even if the original code did it as a mistake). 

--
Greg Comeau / 4.3.10.1 with C++0xisms now in beta!
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?