Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!rochester!pt.cs.cmu.edu!pt!dld From: dld@F.GP.CS.CMU.EDU (David Detlefs) Newsgroups: comp.lang.c++ Subject: Re: unions and classes with constructors Message-ID: Date: 15 Feb 89 15:48:21 GMT Organization: CMU CS Department Lines: 85 << Andrew Wright points out that there are cases in which the prohibition against having objects of classes with constructors as members of unions is inconvenient; the YACC %union construct is such a case. He proposes removing this restriction for certain cases. >> I don't think this is a great idea, because it invalidates an invariant that C++ goes to great lengths to protect: if a class has a constructor, then you can assume that *any* object of that class has had a constructor called before you get to see it. I find this very comforting, and would hate to see it have "except for's" put in it. However, I agree that not being able to put class objects in union-type things is a problem. And I agree with the spirit of your solution. Let me cast in another light: add a tagged union construct, like the "variant" of CLU (and, I believe, Mesa.) The project I'm working on here at CMU is called Avalon/C++, and extends C++ to support transaction-based programmings and persistent objects. One of the extensions Avalon/C++ adds is such a variant construct (Stewart Clamen was the main implementor of this.) The declaration variant foo { int x; char* str; bar b; }; declares a variant that can be in one of four states x, str, b, or the special void state. Foo can be thought of as a class with a null constructor, which initializes the variant object to be in the void state. The above declaration declares member functions bool is_void(); bool is_x(); bool is_str(); bool is_b(); void set_void(); void set_x(int); void set_str(char*); void set_b(bar&) int value_x(); char* value_str(); bar& value_b(); A foo object is initially in the void state; you use a set_??? operation to put it in a state, and the is_??? and value_??? operations to manipulate it. We are considering whether it would be worthwhile to add a special control structure to manipulate variants (like the CLU "tagcase") to the language. Unlike unions, variants could be used in a type-safe way. I would claim that there are just about no legitimate uses for untagged unions that tagged unions would not serve just as well, in a more error-free way. Also, if a program uses variants instead of unions, various other benefits accrue. For example, since all types would then be run-time determinable, it would be possible for a compiler to automatically add general procedures for dumping objects to files and reading them back. My own feeling is that an alternative to unions and lack of parameterized types are the two main things that keep C++ from being as good as any programming language there is. I'm happy that work is proceeding on parameterized types; perhaps there will eventually be an extension along these lines someday. I don't think it breaks anything; the major criticism is that it overlaps to closely with the function of "union." I think the extra safety is worth it. (BTW, I'd really like to see some sort of empirical data on how many of the errors that occur in real C programs would be preventable by different language decisions -- like garbage collection, variants, assignment as a statement instead of an expression to eliminate =/== bugs, etc. If anyone has a reference for such a study, please let me know.) -- Dave Detlefs Any correlation between my employer's opinion Carnegie-Mellon CS and my own is statistical rather than causal, dld@cs.cmu.edu except in those cases where I have helped to form my employer's opinion. (Null disclaimer.) --