lippin@ragu.berkeley.edu (The Apathist) (08/01/90)
My pet peeve with C++ is that (accordong to CFront and a too-close reading of the AT&T language description) initializers for static data members of a class are in the public scope, rather than the scope of the class. Thus in a situation like this: class groupmember { public: static const groupmember zero; ... Zero can only be initialized through a public constructor, and even that constructor cannot be given any constants private to the class. As a remedy, I propose: 1) That the initializer of a data member have access to all members of the class. 2) That when the type of a static data member of a class is the class itself, aggregate initialization (e.g., {0,0,0}) be allowed. 3) That when the type of a static data member of a class is the class itself, ctor-initializers (e.g., :baseclass(17),somemember(0)) be allowed, provided that if any members are ctor-initialized, no aggregate initialization may follow. Aggregate initialization of structs and classes is something I've always found awkward (and non-robust), so I wouldn't really mind seeing it dropped entirely in favor of ctor-initializers -- although for the sake of the past, I suppose it must be kept. --Tom Lippincott lippin@math.berkeley.edu "Every action of theirs, that seems to them an act of their own free will, is ... in bondage to the whole course of previous history." --Leo Tolstoi
lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) (08/01/90)
In article <1990Aug1.030632.2273@agate.berkeley.edu> lippin@math.berkeley.edu writes: >My pet peeve with C++ is that (accordong to CFront and a too-close >reading of the AT&T language description) initializers for static data >members of a class are in the public scope, rather than the scope of >the class. I don't believe the initializers for static data members of a class are in the public scope. Consider the following: #include <stream.h> class X { public: static const int i; static const int j; }; const int X::i = 1; const int X::j = i; int main() { cout << "X::i = " << X::i << ", X::j = " << X::j; } This compiles cleanly with cfront 2.0. This proves that the initialization of X::j is done in the scope of the class. My understanding is that whenever you define something which is prefixed with classname::, you are in the scope of `classname'. This is how you can define member functions outside of the class declaration and still be within the scope of the class. >class groupmember { > public: > static const groupmember zero; > ... >Zero can only be initialized through a public constructor, Zero can be initialized with a private constructor. Embellishing your class a bit we have: #include <stream.h> class groupmember { public: static const groupmember zero; void f() const { cout << "p = " << p << "\n"; } private: int p; groupmember() { p = 1; } }; groupmember const groupmember::zero = groupmember(); int main() { groupmember::zero.f(); return 0; } // will print 'p = 1' Again, this compiles cleanly under cfront 2.0, so the initialization of groupmember::zero is again in the scope of the class. -- Mike Lijewski (H)607/277-0394 (W)607/254-8686 Cornell National Supercomputer Facility ARPA: mjlx@eagle.cnsf.cornell.edu BITNET: mjlx@cornellf.bitnet SMAIL: 1122 Ellis Hollow Rd. Ithaca, NY 14850
bs@alice.UUCP (Bjarne Stroustrup) (08/01/90)
The initializer for a static member IS in the scope of the class of the object being initialized. See section 8.4 of the manual (page 150 of the ARM). A general plea: I realize that many of you haven't yet managed to get your hands on a copy of the AT&T 2.1 reference manual or Ellis&Stroustrup: The Annotated C++ Reference Manual, Addison-Wesley (commonly referred to as the ARM), but please try to remember that this is comp.STD.c++ and try to support arguments/requests with references to the most recent draft working document (currently that reference manual - AT&T 2.1 and the reference manual proper in the ARM are identical). The point is that this would minimize confusion, especially confusion arising from people referring to different documents as ``the manual'' and different implementations as ``the compiler.''
lippin@ragu.berkeley.edu (The Apathist) (08/03/90)
The counterexample Mike Lijewski proposes to my claimed problem with
the C++ definition compiles correctly on my CFront -- however, this
example does not:
(I've also reworked the example to clarify the reason that this
construction be appropriate. Imagine a bounded integral type, with
distinguished constants for the min and max.)
class bounded {
public:
static const bounded min;
static const bounded max;
private:
int p;
static const int maxp;
bounded(int x) { p = x; }
};
const int bounded::maxp=3;
const bounded bounded::min=0;
const bounded bounded::max=maxp;
My CFront declares the last line invalid, saying that maxp is not
defined. But now the problem is not so clear-cut to me; perhaps this
implementation is wrong?
Also, I implied in the original article that aggregate initialization
is not allowed for classes. To clarify, it is allowed for classes
that have no base classes, private or protected members, and no
virtual functions, but not otherwise.
--Tom Lippincott
lippin@math.berkeley.edu
) (08/03/90)
In article <> lippin@math.berkeley.edu writes: >const bounded bounded::max=maxp; { maxp was a member of bounded } > >My CFront declares the last line invalid, saying that maxp is not >defined. But now the problem is not so clear-cut to me; perhaps this >implementation is wrong? Maybe I just haven't worked with this, but it seems to me that the scope declarations on one side of an assignment wouldn't apply to the other, at least not by default. Thus, since you didn't specify that maxp was a member of bounded, it looked in the local scope. Did you try: const bounded bounded::max=bounded::maxp ? If this isn't the way things work, it should be, in my opinion... And if this is what you said in your message, forget this, but I don't think it is. ==GROWF!
rfg@NCD.COM (Ron Guilmette) (08/04/90)
In article <1990Aug2.214222.14165@agate.berkeley.edu> lippin@math.berkeley.edu writes: >const int bounded::maxp=3; > >const bounded bounded::min=0; >const bounded bounded::max=maxp; > >My CFront declares the last line invalid, saying that maxp is not >defined. But now the problem is not so clear-cut to me; perhaps this >implementation is wrong? No. RTFM, then try: const bounded bounded::max=bounded::maxp; + + + + + + + + -- // Ron Guilmette // C++ Entomologist // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // Motto: If it sticks, force it. If it breaks, it needed replacing anyway.