Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!caen!Firewall!uunet!mcsun!ukc!dcl-cs!aber-cs!athene!pcg From: pcg@aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.lang.c++ Subject: Re: Common data structures Message-ID: Date: 14 Jun 91 17:39:52 GMT References: <1991Jun10.200429.26713@lynx.CS.ORST.EDU> <1991Jun11.061402.21934@lth.se> Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 106 On 12 Jun 91 13:34:50 GMT, bill@robots.ox.ac.uk (& Triggs) said: bill> I would agree with Dag Bruck that any real list package must bill> let objects be members of multiple lists I believe that this particular example is the core of the difficulties of making a good reuse oriented language. The issues are very subtle, and only using pointers solves them, if by gross oversimplification, in current languages. It is true but not sufficient to say that: bill> However if you have a parametrised list class, you can always use bill> it to store pointers or references to objects rather than the bill> objects themselves, whereas if you have a 'list-of-pointer' class bill> you can't use it to store real objects. Yet as to: bill> - there are too many toy C++ examples and not enough real bill> implementations about at present! This is inaccurate; there are whole operating systems and major applications (in the hudnreds of thousands of line each range) in C++. It is true though that all these systems have been possible because tha authors, when in tight spots, have solved them by cheating, like in C (casts and other horrible things :->). bill> Do other people share my feeling that C++ is not quite making the bill> grade as far as code reuse goes? - All of the 'solutions' I see bill> seem to be convoluted, bulky, and difficult to use. bill> In particular, too many little 'helper' and 'wrapper' functions bill> seem to be required for hygiene and sanity... I agree with you; I think that there is little understanding of typing and modularization issues inc omputer science. I understand them better than most, IMNHO, and I am amused by all the searching in the dark that goes on. bill> Maybe we should all be using sm*llt*lk ::-)) Smalltalk, and other similar languages, resolve many issues by simply using references and late binding everywhere, which is bit overkill. The challenge is not to build a language that works in the general case, but one that also can be tailored to special cases efficiently. I reckon that this can only be done with symbolic evaluation techniques (supercompiling, and other earlier concepts). In any case C++ is unique in being, bey design, an OO systems implementation language. This means that it must be lean enough to allow you to write a production Smalltalk implementation in it. This is a big constraint, and a big challenge. Too bad that just like with C, C++ is being used also in application contexts where a less systems oriented language, for example Objective C, could be used. bill> Libg++ is OK I guess, but it would be nicer if you didn't need to bill> include an entire separate list implementation for each type of bill> list you have - a better solution would probably be a really tight bill> & nasty void*-chasing core implementation with a fashionable bill> replicatable C++/template wrapper class to interface with it. How do you think are template classes implemented in most C++ compilers that have them? Just like LIBG++ does, a simple preprocessor, just like generics in Ada. A sumbolic reduction compiler could do much better. Some similar technology has been described, but I am not sure it has been implemented. bill> [ ... ] so we might have to sort out this silly 'constructors are bill> not real functions' business [ARM 12.1 p 265]. An explicit bill> constructor call 'bytes->Foo(...)' or '((Foo*)bytes)->Foo(...)' bill> OUGHT to be a legal construct creating a Foo in the given (void*) bill> bytes, just as an explicit destructor call is legal [ARM 12.4]. It is legal indeed. C++ here is very unelegant; a difference is made between the constructor *syntax* and the constructor *function*, and between the new operator and 'operator new'. In particular by using the so called placement syntax for 'operator new' one can invoke just the constructor. In other words while new Foo(...) is an invocation of the new operator that is equivalent to (if it were legal): (Foo::operator new(sizeof (Foo)))->Foo::Foo(...) this invocation of the new operator (where 'bytes' is some suitable pointer): new(bytes) Foo(...) does not imply any call to 'operator new', and is equivalent to (if it were legal): ((Foo *) bytes)->Foo::Foo(...) as you require. The placement syntax is used to construct object for which space has already been allocated. This is typically used for shared memory or otherwise persistent objects which are to be created at a specific address. Admittedly the distinction between the new operator and 'operator new' is a bit subtle and confusing... The ice is particularly thin here :-). -- Piercarlo Grandi | ARPA: pcg%uk.ac.aber@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk