Xref: utzoo comp.lang.c++:8270 gnu.g++.bug:1984 Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!uunet!mcsun!ukc!dcl-cs!aber-cs!odin!pcg From: pcg@cs.aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.lang.c++,gnu.g++.bug Subject: Linkage of static members Message-ID: Date: 29 Jun 90 13:39:13 GMT References: <10460@batcomputer.tn.cornell.edu> <274@taumet.com> <31208@cup.portal.com> Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 78 In-reply-to: wmmiller@cup.portal.com's message of 27 Jun 90 23:42:31 GMT 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