[gnu.g++.bug] Linkage of static members

pcg@cs.aber.ac.uk (Piercarlo Grandi) (06/29/90)

In article <31208@cup.portal.com> wmmiller@cup.portal.com (William
Michael Miller) writes:

   If allowed, "static" in the definition would mean that the member
   had internal linkage, which contradicts the statement in the ARM,
   section 9.4, that "static members of a global class have external
   linkage."

Ahh, but consts have internal linkage unless _explicitly_ specified
extern. Which rule prevails?

   The correct rule for static members (data and functions) is to put
   the "static" modifier in the class declaration and omit it in the
   definition.

This would be wonderful... But where is it said that a storage class
specifier is illegal in the definition of a static class member?

The following snippet of code compiles without errors whatsoever under
g++ 1.36.x:

    struct s { static v; static const c; static f(); };

    static 		s::v = 1;		// external
    static const 	s::c = 2;		// external
    static 		s::f() { return; }	// internal

    struct b { static v; static const c; };

    static		b::v;			// external
    static const	b::c;			// external BSS

    struct e { static v; static const c; static f(); };

    extern 		e::v = 1;		// external
    extern const 	e::c = 2;		// external
    extern 		e::f() { return; }	// external

    struct t { static v; static const c; static f(); };

    typedef		t::v;			// external, typedef ignored
    typedef const 	t::c;			// external BSS, typedef ignored
    typedef		t::f();			// oh my... completely ignored

And the generated code is (slightly compactified):

    #NO_APP
    gcc_compiled.:
    .globl _s$v; .data; .even;_s$v: .long 1
    .text; .even; f__1s: link a6,#0; jra L1; L1: unlk a6; rts
    .globl _e$v; .data; .even;_e$v:	.long 1
    .text; .even; .globl _f__1e; f__1e: link a6,#0; jra L2; L2: unlk a6; rts
    .comm _t$c,4
    .comm _t$v,4
    .globl _e$c; .even;_e$c: .long 2
    .comm _b$c,4
    .comm _b$v,4
    .globl _s$c; .even;_s$c: .long 2

There is clearly some problem here with G++ 1.36.x, but would anyone
care to explain to Michael Tiemann what should be done here? Quoting
chapter and verse of some reliable (time stamped, given the torrid pace
of C++ evolution) source?

Note that I have my own ideas about all this mess; just like all the
confusion about member pointers is caused by the useless notion of
member function, and that around MI is caused by the erroneous notion of
prefixing, all the trouble here is caused by the lack of a notion of
class objec, or the unresolved tension between class-as-module and
class-as-object-template.

In other words, to clarify C++ in a consistent way, you have to jettison
or restructure some of its most critical areas...
--
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

wmmiller@cup.portal.com (William Michael Miller) (07/01/90)

pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
> Ahh, but consts have internal linkage unless _explicitly_ specified
> extern. Which rule prevails?

There's no conflict.  The rule to which you refer states: "A name of file
scope that is explicitly declared const and not explicitly declared extern
is local to its file" (ARM 3.3).  Const class members do not have file
scope.

> This would be wonderful... But where is it said that a storage class
> specifier is illegal in the definition of a static class member?

It's not as explicit as one might like, and I expect that X3J16 may want to
add some wording to the description here.  It is implicit, however, in a
comparison of sections 3.3, 7.1.1, and 9.4 of the ARM.  3.3 and 9.4 say that
a name declared in a class as static has external linkage.  3.3 and 7.1.1
say that a name at file scope specified static has internal linkage.  7.1.1
says that all linkage specifications for a name must agree and gives
examples where it is illegal to specify a name as static once it has already
received, even implicitly, external linkage.

(Rereading these two comments back-to-back make it evident that the
terminology in the ARM needs to be tightened up: const class members don't
have file scope because they're declared inside a class; however, static
class members *must* be defined at file scope.  Perhaps concepts like
"introducing declaration" and "defining declaration" should be used.)

> Note that I have my own ideas about all this mess; just like all the
> confusion about member pointers is caused by the useless notion of
> member function, and that around MI is caused by the erroneous notion of
> prefixing, all the trouble here is caused by the lack of a notion of
> class objec, or the unresolved tension between class-as-module and
> class-as-object-template.

You seem to find a lot of problems that don't particularly seem like
problems to me.  C++ is clearly not the most elegant, concise, and formally
pure language conceivable, but I don't think it's as fundamentally flawed as
you do.

------------------------------------------------------------------------------
William M. Miller, Glockenspiel, Inc.; P. O. Box 366, Sudbury, MA 01776-0003
wmmiller@cup.portal.com         BIX: wmiller            CI$: 72105,1744