Path: utzoo!attcan!uunet!mcvax!ukc!reading!cf-cm!cybaswan!eeartym From: eeartym@cybaswan.UUCP (Dr R.Artym eleceng ) Newsgroups: comp.lang.c++ Subject: Re: Friend specifier considered harmful Message-ID: <86@cybaswan.UUCP> Date: 14 Sep 88 01:40:31 GMT Organization: University College of Swansea Lines: 141 Letter 2 --- I'm posting this on behalf of MARC SHAPIRO: -------------------------------------------------------- * From shapiro@fr.inria.sor Mon Sep 12 10:27:32 1988 * Organization: INRIA, BP 105, 78153 Le Chesnay Cedex, France * telephone +33(1)39-63-55-11, telex 697033 F, telecopy +33(1)39-63-53-30 * To: eeartym@uk.ac.swan.pyr * Subject: plexes and friends I reply to your reply. Date: 12 Sep 88 02:14:52+0000 From: "Dr R.Artym eleceng"An interesting spec; what was your intended application for plex objects? In our application (a distributed OS) we have a things similar to Unix file descriptors, i.e. capabilities accessed by indexing a capability table in the kernel. Currently we use C++ vectors, but we are constantly running into the limitations of vectors. Dynamic allocation is a lot better. Plexes can also be used as efficient queues. > These 3 classes are all friends of each other. Since the actual > data of a plex is the contents of the chunks, the plex better have > friend access to chunk. Why? To me, all this says is that a plex needs to be able to create a chunk from the data supplied. A chunk is of fiexed (but arbitrary) size, and contains any number of elements. The plex creates a chunk with a single element, and the adds more (or removes them) until the chunk is full; then a new chunk is created. Therefore the plex needs access to its chunks (not directly to the chunk representation, though). > Chunk also has friend access to plex; this is > not strictly necessary (actually, it's a bit unclean) but the code is > more readable because the operations on the list as a whole are partof > plex, I think this is a necessary evil of linked lists. The list descriptor has a pointer to the first chunk, which has a pointer to the next chunk. Therefore list manipulation is necessarily distributed over the descriptor and the chunks. This issue is usually avoided by not making chunks a real class. > whereas operations concerning a single chunk and its immediate > neighbours are in chunk. However, you don't say why this good partitioning of operations is only achievable by giving chunks friend access to plex, and I don't see such a need at all. The issue is protection. A plex stores elements of type T into a list of chunks. Both plex and chunk are ``parameterized'' by type T (faked with macro-expansion). Because of the limitations of macro-expansion and of header files, they must be defined in the same .h file. However, I don't want clients to access the chunks. Therefore I make all the chunk operations private, and I give the plex access to them by making it a friend. When paramterized classes are added to C++, maybe will I be able to hack protection differently by a careful distribution of modules in different files, but I prefer explicit protection (by private and friend attributes) rather than implicit (by files). > Finally, iterator has access to plex for efficiency. The whole idea > of an iterator is to abstract from the many individual operations > needed to access elements in succession; might as well do that > efficiently. Friend access is not necessary for efficiency; inline functions appro- priately chosen can do this for you with equal effectiveness. Once again, the issue is protection. The iterator *does* access the plex via inline functions, but these must not be visible to the general public. They are in the private section of plex, and made visible to iterator with the friend attribute. > A chunk may modify the plex, in > order to thread itself onto the linked list. I consider this to be an ill-structured and dangerous approach. See my comment on ``necessary evil'' above. > The plex may modify a > chunk, in order to store a datum in it. Notice that you're not really modifying a chunk, but the contents of the cell where the old chunk used to be! No. See my explanation of chunks, above. > All read access to fields is mediated by inline functions, as well as > all the ``high-level'' write operations (like storing a datum). Only > those write operations which update the specific representation set > the corresponding fields directly. This is good, so that if I change > the representation I know exactly where to change the code. Using your own reasoning, the updates should also be done with inline members --- then you'll have only one place to look! Not true. If I change my representation (e.g. to use a hash table instead of a list) then all of my list updates have to be ripped out and entirely replaced with something new. Therefore it doesn't help to ``abstract'' them into procedures; in fact, that would hide the purpose of the code. > Finally, I make a great use of assertions and invariants to make sure > at all times that my assumptions are correct and the structure is not > broken. Can you give me details of how you do this? I'm writing an article on this topic, which I'll send to you. P.S. I think this material would be of interest to the newsgroup. If you agree, please post your original letter and when I see it I'll post this reply. Further installments will then make sense to our readers! Fine with me, except that I didin't keep a copy. Feel free to forward my messages to the net. Marc Shapiro INRIA, B.P. 105, 78153 Le Chesnay Cedex, France. Tel.: +33 (1) 39-63-53-25 e-mail: shapiro@inria.inria.fr or: ...!mcvax!inria!shapiro -------------------------------------------------------- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Keywords: Parallel, Applicative, and Object-Oriented Languages and Systems --------------------------------------------------------------------------- Dr. Richard Artym, + UUCP : ..!ukc!pyr.swan.ac.uk!eeartym Electrical Engineering Dept., + JANET : eeartym@uk.ac.swan.pyr University of Wales, + Phone : [(0792) or (+44 792)] 295536 Swansea, SA2 8PP, + Fax : [(0792) or (+44 792)] 295532 U.K. + Telex : 48358 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~