[comp.lang.c] 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.''

geoff@world.std.com (Geoff Collyer) (04/09/91)

Ian G Batten:
>>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;''.

ANSI compilers are a low-priority problem for us.  We prefer to write
code that ANSI and Classic compilers can accept (without ifdefs), but
this is an ugly case.  Some Classic compilers (including the original one,
if memory serves) can't cope with forward static declarations at all.

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).
The whole situation is a mess; we may just try to rearrange declarations
to avoid forward static declarations altogether.

Ian Lance Taylor:
>Still, in the long run it would probably be better to change the code (I
>have no idea what that would involve).

Indeed.  But to what?
-- 
Geoff Collyer		world.std.com!geoff, uunet.uu.net!geoff

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

gwyn@smoke.brl.mil (Doug Gwyn) (04/10/91)

In article <1991Apr9.055250.24257@world.std.com> geoff@world.std.com (Geoff Collyer) 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;''.
>this is an ugly case.  Some Classic compilers (including the original one,
>if memory serves) can't cope with forward static declarations at all.

I've never seen a UNIX C compiler that had a problem with multiple
declarations of the same object with static linkage, so long as all
declarations of the object included the "static" storage specifier.
It's the mixing of "extern" and "static" that causes the trouble,
but then there is no reason to do that in the first place.

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

In article <15775@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>... Some Classic compilers (including the original one,
>>if memory serves) can't cope with forward static declarations at all.
>
>I've never seen a UNIX C compiler that had a problem with multiple
>declarations of the same object with static linkage, so long as all
>declarations of the object included the "static" storage specifier.

Sorry Doug, you lose.  The original Ritchie compiler refuses to accept
such multiple declarations.  (I just tried it, to be sure my memory
was correct.)
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (04/13/91)

In article <1991Apr10.161742.21920@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>In article <15775@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>I've never seen a UNIX C compiler that had a problem with multiple
>>declarations of the same object with static linkage, so long as all
>>declarations of the object included the "static" storage specifier.
>Sorry Doug, you lose.  The original Ritchie compiler refuses to accept
>such multiple declarations.  (I just tried it, to be sure my memory
>was correct.)

Hm, I guess the reason I don't recall that is that we upgraded our C
compiler on our 6th Edition UNIX system to a 7th Edition flavor as
fast as I was able to incrementally do so.  (Bootstrapping to a new
augmented version was a bit tricky.)

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

In article <15815@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>>I've never seen a UNIX C compiler that had a problem with multiple
>>>declarations of the same object with static linkage...
>>Sorry Doug, you lose.  The original Ritchie compiler refuses to accept
>>such multiple declarations.  (I just tried it...
>
>Hm, I guess the reason I don't recall that is that we upgraded our C
>compiler on our 6th Edition UNIX system to a 7th Edition flavor as
>fast as I was able to incrementally do so...

I don't think that's the reason, because I was actually speaking of the
7th Ed compiler.  (And a derivative of it is what I've got available
for testing.)
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  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.