[news.software.b] Redeclaration of Variables extern/static

igb@fulcrum.bt.co.uk (Ian G Batten) (04/08/91)

C News, amongst other things, has declarations of ``extern int foo;'' in
either a header or towards the top of a file, and later has ``static int
foo;''.  An example is found in libc/datetok.c or libc/getdate.y.  This
compiles happily with V.2, V.3, V.4, SunOS 4.0, gcc -traditional or gcc
in ansi mode.  In the last case it generates a warning about
redeclaration.

On an IBM RS/6000 (it wasn't my idea) in generates an identifier
redeclared error and exits during compilation.  Lint on an RS/6000
merely reports the redeclaration as a warning.  This is great: a C
compilers that objects to code lint merely warns about.

Can anyone quote chapter and verse as to the legality of this?  As I
want to compile C news, can anyone suggest a workaround?  We've had the
RS/6000 for a few days now and kids, I'll now believe any story, however
bad...

ian

ian@airs.UUCP (Ian Lance Taylor) (04/09/91)

In article <^R+_H3-@uzi-9mm.fulcrum.bt.co.uk> igb@fulcrum.bt.co.uk (Ian G Batten) writes:
>C News, amongst other things, has declarations of ``extern int foo;'' in
>either a header or towards the top of a file, and later has ``static int
>foo;''.
>
>Can anyone quote chapter and verse as to the legality of this?

The ANSI C standard 3.1.2.2:

``...

If the declaration of a file scope identifier for an object or a
function contains the storage-class specifier *static*, the identifier
has internal linkage.

If the declaration of an identifier for an object or a function
contains the storage-class specifier *extern*, the identifier has the
same linkage as any visible declaration of the identifier with file
scope.  If there is no visible declaration with file scope, the
identifier has external linkage.

...

If, within a translation unit, the same identifier appears with both
internal and external linkage, the behavior is undefined.''

So in the case you mention, the behavior is undefined.  This means
that according to the standard, the compiler can do anything it
pleases, specifically including ``terminating a translation.''  Of
course, in this particular case that's pretty tacky.  Still, in the
long run it would probably be better to change the code (I have no
idea what that would involve).
-- 
Ian Taylor              airs!ian@uunet.uu.net              uunet!airs!ian
First person to identify this quote wins a free e-mail message:
``But this machine chews all kinds of paper into a thick porridge that no
  chemist in the world, however skilled a criminal he may be, can read.''

henry@zoo.toronto.edu (Henry Spencer) (04/10/91)

In article <1991Apr9.055250.24257@world.std.com> geoff@world.std.com (Geoff Collyer) writes:
>Henry's opinion (I hope I'm not misquoting him) is that there are certain
>cases that ANSI doesn't cover either (forward static arrays, as I recall).

Forward static arrays of unspecified size are the problem.  For those, there
simply is no portable way to write a forward declaration, and we're simply
going to have to avoid doing this.

For everything else, the problem is not unsolvable, merely awkward.  Old
compilers won't take static forward declarations at all, while new ones 
won't take extern forward declarations for static objects.  The choice is
between avoiding forward declarations entirely, using a macro so you can
make them extern or static as required, or just giving up and making the
objects extern.  These are all somewhat distasteful.

While we do intend to be ANSI compatible, our development systems have
historically used old compilers, and it will be quite a while before the
last lingering glitches get sorted out.
-- 
"The stories one hears about putting up | Henry Spencer @ U of Toronto Zoology
SunOS 4.1.1 are all true."  -D. Harrison|  henry@zoo.toronto.edu  utzoo!henry

sanders@cactus.org (Tony Sanders) (04/16/91)

In article <^R+_H3-@uzi-9mm.fulcrum.bt.co.uk> igb@fulcrum.bt.co.uk (Ian G Batten) writes:
>On an IBM RS/6000 (it wasn't my idea) in generates an identifier
>redeclared error and exits during compilation.
To work around the problem you can simply change the name of the thing
so it doesn't conflict with anything else (if it's called foo rename it
to my_foo) and then remove the "static".

Ugly but it works.

-- sanders@cactus.org
I am not an IBM representative, I speak only for myself.
I have a wonderful proof that emacs is better than vi, only this .sig
    is too small to contain it.