HDTenEightyP/NetNews huggingface dataset:
From: shang@corp.mot.com (David (Lujun) Shang)
Subject: Downcast and Reverse Offset
Reply-To: shang@corp.mot.com
Organization: Motorola, Inc., Software Research and Development, Rolling Meadows, IL. 60008
Date: Thu, 10 Sep 92 01:58:57 GMT


The topic has been discussed sometime before.

I got an email from someone to point out to me that reverse offset is not
required for downcast. And I replied to agreed to this point of view at 
that time. But thinking over the problem today, I find that reverse offset 
is still necessary. 

[I'm sorry I lost your email so I cannot reply to you directly.]

Consider the following example:

class A {};
class B1:A {};
class B2:A {};
class C: B1,B2 {};

C c;
B1 * b1p;
B2 * b2p;
A * ap1, * ap2;
C * cp1, * cp2;

b1p = &c;
b2p = &c;
ap1 = b1p;   // ap1 is pointing to the B1::A base of the object c
ap2 = b2p;   // ap2 is pointing to the B2::A base of the object c

The problem is that how the compiler knows which base of the object the base  
pointer is pointing to:

cp1 = (C*) ap1;
cp2 = (C*) ap2;

Therefore, reverse offset is still necessary.

It is quite ridiculous that BC++ V3.1 does not allow the type cast in

cp1 = (C*) ap1;
cp2 = (C*) ap2;

where both ap1 and ap2 are actually pointing to an object of C! On the other  
hand, cast from an arbitrary class is allowed:

cp1 = (AnyOtherClass1 *) anyOtherObjectPointer1;
cp2 = (AnyOtherClass2 *) anyOtherObjectPointer2;

???!!!

David Shang



Newsgroups: comp.lang.c++
From: dag@control.lth.se (Dag Bruck)
Subject: Re: zero-length datatype
Organization: Department of Automatic Control, Lund, Sweden
Distribution: comp
Date: Sat, 12 Sep 1992 15:14:40 GMT

In <comp.lang.c++> tmb@idiap.ch writes:
>
>Compiler writers might be encouraged to issue a warning when a
>declaration of "void f(void);" occurs in the C++ language context
	....
>Maybe the interpretation of "void f(void)" as a function taking no
>arguments could eventually be phased out in the C++ language context.

The point is that C++ should be as compatible as possible with ISO C.
This is one of strongest requirements for the C++ standardization
committees.

			-- Dag
Newsgroups: comp.lang.c++
From: mrhagger@athena.mit.edu (Michael R Haggerty)
Subject: Proposal: Subscripting with multiple arguments
Organization: Massachusetts Institute of Technology
Date: Mon, 14 Sep 1992 18:29:42 GMT

Hi,

I have been using C++ for numerical work, and one of the changes which would
be most useful would be to allow the subscription operator to take multiple
parameters.  This would make it much simpler to define classes for multi-
dimensional matrices without the nuisance of having to define a helper class.
The concept should not be such a shock to anyone, as the subscript operator
is already allowed to take non-integer arguments so is already significantly
extended from the C subscript operator.

The only way of getting around this deficiency and also avoiding a matrix_row
helper class is to making subscripting an operation that uses the function call
operator; i.e.

Matrix2d M(10, 10);
M(4, 5) = 15.0;

rather than the (in my opinion) much more natural

M[4, 5] = 15.0;

which would require a definition like

double &Matrix2d::operator[] (int i, int j) {...}

As a benefit, I think that it should be easier to generate good code from the
two-argument version than from the version which uses a helper class.  In
numerical work, efficiency is everything.

Of course there is a slight drawback: the proposed notation is presently
seen as a usage of the comma operator within a (single argument) subscript.
Correct me if I'm wrong, but I believe that this is a rather rare construct
and could be effected by

M[(4,5)] = 15.0;

that is, the extra parenthesis are necessary to force the internal expression to
be seen as a comma operator.

Am I being naive to suppose that the change could be made without stepping on
too many people's toes?  Has this change been considered before?  What does it
take to get a proposal like this seen by the powers-that-be?

Yours,
Michael Haggerty
mrhagger@athena.mit.edu
From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: General Datastructure Design Question
Date: 9 Sep 92 18:37:52 GMT
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: iwelch@agsm.ucla.edu's message of 8 Sep 92 18:45:16 GMT

In article <1992Sep8.114516.4105@mic.ucla.edu> iwelch@agsm.ucla.edu (Ivo Welch) writes:

|I am trying to define a simple data structure, like a binary tree, which can
|be used by any other data structures. So, I decided to go the C++ way, rather
|than passing byte sizes of structures as I would in C.
|
|My guess was that a good design would define an abstract "TreeNode" class on
|which my BinaryTree class would operate. This abstract TreeNode class
|declares 2 functions, (fix, compare). A user would define her own "Node"
|class, inheriting the abstract class, which [a] contains the data and [b]
|defines the fix() [=copy] and compare() functions. The instantiated user-node
|object carries with it the information of what compare and fix functions
|operate on it, because it is derived from a virtual abstract class.

Personally, I don't like that style of programming. A TreeNode
containing a Foo should not be the same as a TreeNode inheriting from
a Foo.

It may be better simply to "simulate" templates until you get a
version of GNU C++ that supports them. There are two common ways of
doing this (of which the latter doesn't seem to be well-known):

(1) Using "#define":

#define make_Array_type(BaseType) \
struct Array { \
	BaseType *data; \
	... \
};

(2) Using "#include" (much easier to debug):

===> generic-array.h:

struct Array {
	BaseType *data;
	...
};

===> using generic-array.h

#define BaseType int
#define Array IntArray
#include "generic-array.h"
#undef Array
#undef BaseType

				Thomas.
Newsgroups: comp.lang.c++
From: pat@frumious.uucp (Patrick Smith)
Subject: Re: defining cast operators outside classes
Date: Wed, 9 Sep 1992 00:34:35 GMT
Reply-To: uunet.ca!frumious!pat
Organization: None

steve@taumet.com (Steve Clamage) writes:
|The semantics depend on which non-class declarations are visible,
|which is not normally the case in C++.  (There is a somewhat
|parallel case:  You omit one overloaded function declaration and
|an unintended function is called.  Maybe someone can think of a way
|to solve that problem in the language.)


Here's one expensive, but I think otherwise reasonable, idea.
This doesn't involve any changes to the language; the intent
is for a compiler to produce appropriate warning messages.


During compilation, the compiler would record the formal parameter
types of every function (including inline functions, static functions,
and functions declared but not defined).  It would also record the
actual argument types for every function call, and which function
each call resolved to (compile-time resolution, so calls to virtual
functions should resolve to the base class versions).  All this
information could perhaps be stored in the .o files or in files
associated with the .o files.

At a later point in time, perhaps while linking the executable,
the compiler would scan the list of function calls, and determine
which function each call would resolve to if all the functions
declarations were visible at the point where the call was made.
If the call resolves to a different function than earlier, or if
the call is now ambiguous, then the compiler should issue a warning
message.

It is important to list all the functions declared, not just the
ones defined.  If a function is declared in places where it can't
be used, but not declared in places where it could be used, then
the linker might not include the function definition when linking
the final program.


I guess this is the sort of thing one might expect a C++ lint to do.
As I said, it's probably quite expensive; I don't think I'd want it
done on every compile.  But it might be nice to have a compiler
switch that would allow this checking to be requested occasionally.

-- 
Patrick Smith
uunet.ca!frumious!pat
pat%frumious.uucp@uunet.ca
From: etnkna@hisoy2.etn.ericsson.se (Aksnes Knut-Havard)
Newsgroups: comp.lang.c++
Subject: Renaming
Date: 7 Sep 92 19:31:01 GMT
Distribution: comp
Organization: Ericsson Telecom AS


First; I have not been reading this list for a while, so it is
possible, that my ideas have been discussed before

ARM Section 10.11c suggest  a renaming mechanism to be used when two
class hierarchies are merged by a common derived class, where the same
name is used in both hierarchies, but with different semantics. 

Such a renaming scheme is of interest in another situation too;
sometimes you want to inherit the same class twice, the classical
example is an implementation of a sparse matrix using linked lists,
each element shall be in one row list and one column list. Deriving
linked list twice is not allowed; There are no way to access the
members of the two parent classes in a unambiguous way.

A kludge around this problem is to generate a dummy class inherited
from the parent class and derive both the parent class and the dummy.
The problem with this kludge is that it clobbers the global name
space.

The same problem is well known in the relational database world, when
a query needs to reference the same table twice. The solution is also
well known: An alias for one of the tables is created (The ISO SQL
standard uses the term correlation name.) 

An example in pseudo c++ shows what I mean.

class LinkedListElem;

class MatrixElem: public LinkedListElem row, public LinkedListElem column{
	.
	.
	.
};

using row:: and column:: internally in Matrix and derived classes to
resolve ambiguity

or 

class Matrix: public LinkedListElem row, public LinkedListElem{
	.
	.
	.
};

using row:: and LinkedListElem::

--

-------------------------------------------------------------------------------
Name:	Knut-Hevard Aksnes (ECMA 94) or		Knut-Haavard Aksnes (ASCII)
Ericsson signature: HI/ETN/U/IT KNA		Phone: +47 41 19481
Email: etnkna@hisoy.etn.ericsson.se (internet)  ETN.ETNKNA (memo)
From: larsn@Autodesk.COM (Lars Nyman)
Newsgroups: comp.lang.c++
Subject: buidling COOL on sparc
Keywords: COOL
Date: 11 Sep 92 18:29:12 GMT


Has anybody successfully built COOL w/ Sun C++ (cfront 2.1) ?

I have the default installation setup (w/ CC, cfront, patch etc. 
in /usr/lang/SC1.0) and am having problems in configuring COOL
to find cfront, C++ include directory etc.
I followed the instructions in README.sparc but it doesn't seem to work.
I would appreciate if somebody  has could mail me the changes I need to 
make to COOL's makefiles etc. in order to successfully build COOL.

Lars Nyman (larsn@autodesk.com)
From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: defining cast operators outside classes
Date: 8 Sep 92 00:39:26 GMT
	<1992Sep7.154125.28472@murdoch.acc.Virginia.EDU>
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: gs4t@virginia.edu's message of 7 Sep 92 15:41:25 GMT

In article <1992Sep7.154125.28472@murdoch.acc.Virginia.EDU> gs4t@virginia.edu (Gnanasekaran Swaminathan) writes:

   tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
   : Apparently, it is impossible to define a conversion operator for a
   : class without making the conversion operator a member function.
   : 
   : It would be very useful to be able to define something like the
   : following without having to modify either class MyMatrix or class
   : TheirMatrix:
   : 
   : 	operator MyMatrix(TheirMatrix &m) {
   : 		...
   : 	}
   : 
   : Why was this seemingly arbitrary restriction made? Can it be
   : eliminated in the next version of C++?

   You can achieve what you want by providing a constructor in your
   MyMatrix class that takes a reference to TheirMatrix as its
   argument. For example,

Please read my posting carefully: I don't want to modify either
MyMatrix or TheirMatrix. Perhaps I should have chosen type names of
"TheirMatrix" and "SomeOtherMatrix" to make this even more obvious.

					Thomas.
Newsgroups: comp.lang.c++
From: mcgrant@rascals.stanford.edu (Michael C. Grant)
Subject: Re: zero-length datatype
Organization: Information Systems Laboratory, Stanford University
Distribution: comp
Date: 10 Sep 92 14:20:12


   tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
   : In article <MCGRANT.92Sep7142456@rascals.stanford.edu> mcgrant@rascals.stanford.edu (Michael C. Grant) writes:
   : 
   :    I don't understand why those 4 bytes are causing you such a stink. Perhaps
   :    you could enlighten us as to why a truly zero length data type is even
   :    necessary?
   : 
   : Under the current rules,
   : 
   :       struct nothing {};
   :       HashTable<int,nothing> table(1000000);
   : 
   : table takes up 8Mbytes (on most machines). If you could write
   : 
   :       HashTable<int,void> table(1000000);
   : 
   : table takes up 4Mbytes.

That wasn't my question... I would like an example where I would need to
USE a void data type. In other words, Why is HashTable<int,void> a useful
data type at all, and why can't we simply share code between
HashTable<T1,T2> and another template HashTable<T1> which would be
functionally equivalent to HashTable<T1,void>?

Perhaps, in fact, HashTable<T1> could be a base class for HashTable<T1,T2>,
so as to maximize the possible code reuse...

I don't understand why a well-written C++ program should need to 
operate on data that does not exist. If you give me a good example,
I would appreciate it.

Michael C. Grant
From: dpn2@po.CWRU.Edu (Damien P. Neil)
Newsgroups: comp.lang.c++
Subject: ObjectWindows from TC 3.0 in BC 3.1
Date: 4 Sep 1992 22:41:22 GMT
Organization: Case Western Reserve University, Cleveland, OH (USA)
Reply-To: dpn2@po.CWRU.Edu (Damien P. Neil)
NNTP-Posting-Host: thor.ins.cwru.edu


I have been using Borland's Turbo C++ 3.0 for several months now. One of
the things about it that I like the most is the ObjectWindows library. This
has made Windows programming much easier for me.

A week ago, I bought Borland C++ 3.1. (Irresistable student discount.) It
is much better than TC 3.0, except that it does not contain ObjectWindows.
No problem, thought I. I'll just move the library from TC over to BC. After
all, the support for it is still there, right? (BC 3.1 even includes the
help files for OWL.) Well...I tried to compile a program that uses OWL. I
got one error message in one of the header files, and added a type cast to
it. (BC 3.1 must be more picky.) Now my program compiles fine, but I get
numerous errors for the linker. The linker claims it is unable to find a
number of functions. Not ALL the ObjectWindows functions, just a few.

So, does anyone know if there is any hope for me? Is there any way I can
use ObjectWindows in BC 3.1, and if so, how?

Thanks in advance,

                - Damien 

<This .sig under construction.>
 
Newsgroups: comp.lang.c++
From: steve@taumet.com (Steve Clamage)
Subject: Re: can I 'delete' without a 'new'?
Organization: TauMetric Corporation
Date: Sat, 5 Sep 1992 16:09:32 GMT

peter@kentrox.uucp (Peter Uchytil) writes:

>I can't seem to find any references which indicate whether I can do this
>or not...

The ARM is very explicit on this point, and so should be any C++ text.

You may use 'delete' only with a pointer obtained from 'new', or with
the value zero.  Array syntax must be used with delete if and only if
array syntax was used with the corresonding new.  You may delete the
pointer at most once.

The results of any other usage are undefined.  Here are two ways to
handle the problem of not knowing when to delete a pointer.

1. If you don't know whether the space, even if allocated, should be
deleted, use a flag:
	class X {
	    char* data;
	    int do_del;
	public:
	    X()		{ data = 0; do_del = 0; }
	    X(int s)	{ data = new char[s]; do_del = 1; }
	    X(char* p)	{ data = p; do_del = 0; }
	    ~X()	{ if( do_del ) delete [] data; }
	    char* get_data() { do_del = 0; return data; }
	};
The last function returns a pointer to an internal data structure, so
we don't want to delete the data automatically.

2. If the space might not have been allocated, but if so must always be
deleted, initialize the pointer to zero.  It is always harmless to
delete a null pointer.
	class X {
	    char* data;
	public:
	    X()		{ data = 0; }	// delete will be harmless
	    X(int s)	{ data = new char[s]; }
	    ~X()	{ delete [] data; }
	};
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Newsgroups: comp.lang.c++,comp.std.c++
From: steve@taumet.com (Steve Clamage)
Subject: Re: operator delete[] and NULL
Organization: TauMetric Corporation
Date: Sat, 12 Sep 1992 17:28:13 GMT

matt@centerline.com (Matt Landau) writes:

|Speaking of operator delete[], is the effect of calling delete[] on NULL
|well-defined?  The ARM says plainly that "delete NULL" is legal, and a 
|no-op, but I couldn't find anything explicit about "delete[] NULL", nor
|could I find any implication that operator delete and operator delete[]
|must behave the same way.
|The reason I ask is that, with USL cfront 2.1.12, I have found code that
|crashes intermittantly when asked to delete[] NULL.  I'm wondering if the
|code is correct and cfront is buggy, or vice versa.

The ARM says on p 63:
	"Deleting a pointer with the value zero, however,
	is guaranteed to be harmless."
This sentence immediate follows the syntax production
	deallocation-expression:
		delete cast-expression
		delete [ ] cast-expression
It doesn't restrict the guarantee to single-object deletion.

If your system doesn't allow
	T *p = 0;
	delete [] p;
then that is a bug.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Newsgroups: comp.lang.c++
From: pjl@sparc10.cs.uiuc.edu (Paul Lucas)
Subject: Re: pointer typecasting question...
Organization: University of Illinois at Urbana-Champaign
Distribution: usa
Date: Fri, 11 Sep 1992 14:04:16 GMT

In <1992Sep10.210319.4450@news.columbia.edu> kps@cunixb.cc.columbia.edu (Karthik P Sheka) writes:

>I'm working on a C++ program that is using a C package that is giving
>problems (The package was not meant to be used in C++):

>One C call I make, CreateButton, takes as an arguement, a pointer to a
>function that takes one arguement and returns void:

>void function(int arguement);
>main()
>{
>	CreateButton(function);
>}

[ ... other stuff on using a member-function as a callback elided... ]

*****>	A pointer-to-member is _not_ an ordinary pointer; rather it's
	an offset.  So "no" you can't do this.  This is a very FAQ.
-- 
	- Paul J. Lucas				University of Illinois	
	  AT&T Bell Laboratories		at Urbana-Champaign
	  Naperville, IL			pjl@cs.uiuc.edu
Newsgroups: comp.lang.c++
From: sierhuis@nynexst.com (Maarten Sierhuis)
Subject: Class documentation generator
Reply-To: sierhuis@nynexst.com
Organization: NYNEX Science & Technology, Inc.
Date: Fri, 11 Sep 92 15:25:47 GMT

I am looking for a tool that can generate some kind of documentation (man page style
or something) for my C++ classes. I have C++ header files for my class definitions,
and would like to generate some standard document from that.

I believe that I've seen other people asking for the same, but I have never seen
a reply (probably due to my own faults :-) ).

Anyway, I would like some public domain tool that I can ftp from somewhere.

Thanks in advance for any leads ... doei ... MXS



------------------------------------------------------------------------
Maarten Sierhuis                       NYNEX Science & Technology, Inc.
Member of Technical Staff              Research & Development
                                       Expert Systems Laboratory
E-mail: sierhuis@nynexst.com           500 Westchester Avenue
voice: (914) 644-2352                  White Plains, NY 10604
fax:   (914) 644-2404		       USA
------------------------------------------------------------------------

Newsgroups: comp.lang.c++
From: mccall@mksol.dseg.ti.com (fred j mccall 575-3539)
Subject: Re: GOTO, was: Tiny proposal for na
Organization: Texas Instruments Inc
Date: Wed, 9 Sep 1992 20:54:23 GMT

In <rmartin.715527587@thor> rmartin@thor.Rational.COM (Bob Martin) writes:

>I did not intend to start a religious war.  (Or a quaint discussion.)
>I had no idea that there would be such a reaction.  Structured
>Programming is "old news".  Arguing about whether or not to use gotos
>is like arguing about whether the world is round or flat. The question
>was settled years ago.  

Well, no, it wasn't, except for folks who need a dogma to follow.
Many of us say to avoid them unless they are the most appropriate
structure.  That doesn't seem to be your opinion, though.

>The principles of structured programming were an important advance in
>the science of software engineering.  Those principles are still valid
>today as a guide to structure the implementation of our methods.   We
>should not forget them, and if they are in question, then we should
>discuss them.

There!  You used the key word.  GUIDE.  Not "hard and fast rule".  Not
"cast in concrete, GOTO is the ultimate evil".  GUIDE.

Now if only the rest of your notes reflected that use of the word
'guide', rather than treating structured programming as if it was
carved on stone tablets and handed down from the mountain.

-- 
"Insisting on perfect safety is for people who don't have the balls to live
 in the real world."   -- Mary Shafer, NASA Ames Dryden
------------------------------------------------------------------------------
Fred.McCall@dseg.ti.com - I don't speak for others and they don't speak for me.
From: rmartin@thor.Rational.COM (Bob Martin)
Newsgroups: comp.lang.c++
Subject: Re: Reference as a return type
Date: 8 Sep 92 23:30:51 GMT

car@access.digex.com (Mr. Blue) writes:


|I'm probably asking a question that belongs in FAQ, (and if there
|is such a list of question for this newsgroup I'd be grateful if someone
|emailed it to me)

|Anyway my question is this: Whats the difference between returning a
|pointer to a class and a reference to a class from a member function??
|I mean a reference is just a pointer, isn't it? However I get the feeling
|that the semantics are very different, i.e. copy constructors are called,
|etc. Can someone tell me what happens on the run time stack to contrast
|the 2 cases? I know this is probably a naieve question,but I'm still
|learning so forgive me.


A reference is an lvalue.  A pointer is an rvalue.  Thus, you can use
a member function which returns a reference as the target of an
assignment. 

Also, because references are lvalues, it is illegal for them to be
invalid, they must always refer to a valid object.  (The language
specifies this as a rule, but most compilers can't enforce it) Thus,
when a member function returns a pointer, it might be zero, so you
should test is.  But if it returns a reference, then you "know" that
it is valid and can use it without the test.


--
Robert Martin                        Training courses offered in:
R. C. M. Consulting                       Object Oriented Analysis
2080 Cranbrook Rd.                        Object Oriented Design
Green Oaks, Il 60048 (708) 918-1004       C++
Newsgroups: comp.lang.c++