HDTenEightyP/NetNews huggingface dataset:
From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Zero-length structures and pointer comparisons
Organization: Computer Science, University of Melbourne, Australia
Date: Mon, 21 Dec 1992 11:31:18 GMT

maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

>jimad@microsoft.com (Jim Adcock) writes:
>>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>>|But Jim, it is not implementation defined, it is required that 
>>|pointers to the same object compare equal. It is therefore
>>|legal to have a function:
>>|
>>|	f(X* a, X*b) {
>>|	if(a==b) { /* special case, copy b object */ ... }
>>|	else *a+=*b;
>>|	}
>>|
>>However, if a strictly conforming implementation is presented with a 
>>non-strictly conforming program, such as a program that calls OS
>>virtual memory mapping adjustment routines, or programs that send
>>pointers off the ends of arrays, or programs who don't properly point
>>at objects that correspond to the types of objects they pretend to point
>>at .... in all such cases all bets are off.  
>>
>	I know what you are saying but dont see it.
>ARM p74:"two pointers to the same object compare equal".
>Any program for which this is not true cannot be conforming,
>neither strictly nor non-strictly, it is non-conforming, it is
>not in fact a C++ program.
>
>	Or have I got this wrong?

I think you have got this wrong.
Such a program might be neither strictly nor non-strictly conforming,
but it is still a C++ program, at least in as far as that term is
commonly used.

>	For this reason I think the ARM requirement is unworkable,
>and must be modified. The rule should state that pointers
>derived from the same object directly in the program must
>compare equal. Pointers obtained from the OS need not follow
>this rule, in that case it is implementation defined.
>This is the case for pointers way off the end of an array:
>it is implementation defined.

Remember that the ARM is a reference manual, not a standard.
I believe that the ANSI C standard makes it clear that for
programs that invoke code whose behaviour is "undefined", all
bets are off. (The usual remark is that the system is allowed
to spew frogs from the tape-drive, or something equally ridiculous,
so desires). This is equally true of programs that invoke the
operating system (other than by standard library functions
defined in the ANSI C standard). Any guarantees about the
behaviour of such programs must be made by a standard for that
particular operating system, not by the ANSI C standard.
The same will apply to the ANSI or ISO C++ standard, when
it arrives.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Newsgroups: comp.std.c++
From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: Zero-length structures and pointer comparisons
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Tue, 22 Dec 1992 00:37:52 GMT

In article <9235622.25712@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>
>>pat@frumious.uucp (Patrick Smith) writes:
>>>   p == q   =>   ptrcmp(p,q) == 0
>>
>>	I'm NOT agreeing with this at present. I reject any relationship
>>between p ? q and ptrcmp. On some machines any such relationship
>>might make ptrcmp unimplementable, and thus defeat the proposal completely.
>
>I remain unconvinced that such a relationship is unimplementable on
>some machines.

	On the 486 it is not in general possible to implement
the comparison p==q for arbitrary logical addresses. If p and q
are aliases only the operating system kernel could implement 
the comparison, and if the OS happened not to support this,
p==q could not be implemented.

>
>>It is only Jims suggestion that ptrcmp might always return 0 that
>>makes it possible to make its existence mandatory.
>
>A ptrcmp that always returned 0 would be useless, IMHO.
>

	Not at all. My sort will still order the pointers
into the total order, which in this case is anything.

	This is entirely different from the current situation
where a sort based on the existing implementation defined <
on pointers might not terminate.

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.std.c++,comp.std.c
From: jamesc@swapsdev.state.state.COM.AU (James Cribb)
Subject: Re: Question about sizeof in C/C++.
Organization: Group Treasury, State Bank of NSW
Date:  1 Jan 93 02:19:19 GMT

jimad@microsoft.com (Jim Adcock) writes:
>jamesc@swapsdev.state.state.COM.AU (James Cribb) writes:
>| Given
>|     struct Something*  ps;
>|     unsigned  k;
>| do the C or C++ standards guarantee that
>|     &ps[k] == ((char*) ps) + k * sizeof(struct Something)
>
>No.  The relationship holds only if ... k is less than or equal 
>to the number of elements in the array pointed-to by ps

My code meets those conditions, but just out of interest,
if k is too big, what could cause an inequality (of the addresses)?

	j.c
Newsgroups: comp.std.c++
From: jamshid@ut-emx.uucp (Jamshid Afshar)
Newsgroups: comp.std.c++
Subject: Re: Must derived class reserve space for an empty base class?
Summary: does anyone understand my point?
Date: 26 Dec 92 07:31:46 GMT
Reply-To: jamshidemx.utexas.edu
Organization: The University of Texas at Austin; Austin, Texas

In article <1992Dec24.202339.26224@microsoft.com> jimad@microsoft.com (Jim Adcock) writes:
|In article <85744@ut-emx.uucp> jamshid@ut-emx.uucp (Jamshid Afshar) writes:
||[...] Programmers will continue to do things like
||	class Register {
||	   Set<Register*> alive;
  	  ^woops, I forgot 'static'
||	protected:
||	   Register() { alive += this; }
||	   virtual ~Register() { alive -= this; }
||	   static void foo();  // do something to all registered objects
||	};

|Given that you do not specify your implementation, such as telling us
|what pointer comparisons you use or don't use, its hard to say
|whether your example does or doesn't work under all current C++
|implementations.

I forgot the keyword 'static' in my example, but I thought the
intentions were obvious.  The problem with the above idiom is that
Register() could add the same 'Register*' twice (the second add being
ignored) when constructing a Register-derived object that contains
another Register-derived object as its first data member.

All current and probably future C++ compilers use a hidden vtbl
pointer to implement virtual functions so you probably won't encounter
any problems with the above idiom, but it is "wrong" unless rules are
changed.

|Below find an example that frequently catches programmers off guard.
|Again, C++ pointers DO NOT model any notion of object identity. [...]
|class A { char bsPadding; };
|class B : public A {};
|class C : public A {};
|class D : public B, public C {};
	A* pa1 = (B*)&d;    A* pa2 = (C*)&d;
	if (pa1==pa2)
|		cout << "pointers match\n";
|	else 
|		cout << "pointers don't match -- even though of the same"
|			" type and 'to the same object'!\n";

I know this and I don't have a problem with it.  There are two
different A objects (they would each have separate data members) so I
don't think they are pointers "to the same object".

Jamshid Afshar
jamshid@emx.utexas.edu

Newsgroups: comp.std.c++
From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: Compiler should generate virtual destructors
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Sun, 3 Jan 1993 03:22:28 GMT

In article <lkc2k7INNajv@exodus.Eng.Sun.COM> db@argon.Eng.Sun.COM (David Brownell) writes:
>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>
>> I would like to propose that if a class has virtual functions,
>> then any destructor generated by the compiler will be virtual
>> by default.
>
>Hmmm ... given that I've never seen such nonvirtual destructors be
>anything except bug, I like the idea of fixing this problem.
>
>On the other hand, one of the things I'd really like to see changed is
>how much stuff a C++ compiler does "for me" automagically.  It's a rare
>day when it really does what I need to have done; just how often is
>memory management broken when pointers "owned" by class instances are
>bitwise copied?  

	A decent solution could have been had except for the
extremely unfortunate (IMHO) decision that 'struct' and 'class'
are synonymous (except for public/private defaults).

	For example, how about:

	generate X::X(const X&);

This could only apply to classes and not 'C' structs for compatibility
reasons.

>
>So, a pair of proposals that I'd be happier to see accepted:
>
>   (1)	It is an error for a class to have virtual functions and a
>	nonvirtual destructor.
>	
>   (2a)	C++ compilers don't automagically generate ANYTHING for classes
>	any more:  constructors, destructors, assignment and address-of
>	operators, etc.  If such routines are used but not declared and
>	defined, that is an error.

	Not possible for C-Structs, compiler MUST automagiocally
generate constructors and assignment for these.

	Want to modify (2a) to include 'with virtual functions'?

>
>Or in short, if you want to allow copying, destruction, assignment,
>and so on for instances of your classes, you'll have to explicitly
>provide member functions to support those actions in the interface
>definitions (and implementation bodies) for your classes.

	You do NOT want to have to write the code. Explicit
direction to the compiler to generate the code may be acceptable.

	generate X& operator=(const X&);

>
>Perhaps the specific issues with memory management could be fixed by
>the alternate proposal below:
>
>   (2b)	C++ compilers don't automagically generate those routines
>	(complete list omitted :-) for classes that have members which
>	are pointers or references.  If such routines are used but
>	not declared and defined, that is an error.

	Not compatible with C.

	Personally, I'd like to ban virtual functions from
'structs' and insist structs worked as they do in C.
Also allows nested structs to be globally visible, as in C.

	The classes could be distinct and have different rules.
But it is too late for this.

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.std.c++
From: bright@nazgul.UUCP (Walter Bright)
Newsgroups: comp.std.c++
Subject: Re: wchar_t as a basic type
Keywords: wchar_t
Date: 22 Dec 92 08:53:37 GMT
Reply-To: bright@nazgul.UUCP (Walter Bright)
Organization: Zortech, Seattle

In article <1992Dec9.103811.28262@alf.uib.no> yngvar@novaja.imr.no (Yngvar Foelling) writes:
/Sorry about following up this so long afterwards.  But here's a point that I
/didn't see mentioned in the discussion.
/wchar_t is the type of a wide character constant, i.e. L'x'.
/Walter, you're a compiler writer.  Would you like the idea of making the type
/of a constant, defined in the language, a type from the library?
	It already is. L'x' is a wchar_t, which is defined in the library.
/How would you handle the correct insertion of a string like this:
/cout << L"Wide string constant";
	The compiler "knows" about wchar_t, just like it does now
	for ANSI C. No, it is not as clean as I would like, but the
	L wart is the only one I've found so far.
Newsgroups: comp.std.c++
From: db@argon.Eng.Sun.COM (David Brownell)
Newsgroups: comp.std.c++
Subject: Re: Compiler should generate virtual destructors
Date: 2 Jan 1993 21:35:03 GMT
Organization: SunSoft
NNTP-Posting-Host: argon

maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

> I would like to propose that if a class has virtual functions,
> then any destructor generated by the compiler will be virtual
> by default.

Hmmm ... given that I've never seen such nonvirtual destructors be
anything except bug, I like the idea of fixing this problem.

On the other hand, one of the things I'd really like to see changed is
how much stuff a C++ compiler does "for me" automagically.  It's a rare
day when it really does what I need to have done; just how often is
memory management broken when pointers "owned" by class instances are
bitwise copied?  Arguments I've heard against automagic generation of 
code by the C++ compiler seem to fall into three categories:

    -	Memory management bugs get trivially introduced, both in the
	initial implementations and during subsequent maintainence;

    -	Declaring automagic routines as 'private', with implementations
	that abort, to prevent assigning/copying data structures that
	shouldn't be support those operations (due to various expenses,
	or to design desiderata) is really ugly, and consumes both
	coding and runtime resources;

    -	It's confusing both to beginning and to expert programmers
	(e.g. C ones who are "upgrading" to C++) that private data
	structures be manipulated (and bugs added) by compilers.

So, a pair of proposals that I'd be happier to see accepted:

   (1)	It is an error for a class to have virtual functions and a
	nonvirtual destructor.
	
   (2a)	C++ compilers don't automagically generate ANYTHING for classes
	any more:  constructors, destructors, assignment and address-of
	operators, etc.  If such routines are used but not declared and
	defined, that is an error.

Or in short, if you want to allow copying, destruction, assignment,
and so on for instances of your classes, you'll have to explicitly
provide member functions to support those actions in the interface
definitions (and implementation bodies) for your classes.

Perhaps the specific issues with memory management could be fixed by
the alternate proposal below:

   (2b)	C++ compilers don't automagically generate those routines
	(complete list omitted :-) for classes that have members which
	are pointers or references.  If such routines are used but
	not declared and defined, that is an error.

Existing code compiled with a compiler enforcing (2a) or (2b) would
generate error messages; fixing that code and then recompiling it with
today's compilers (e.g. CFRONT) would not cause any problems at all.

Comments?

- Dave

--
David Brownell                        db@Eng.Sun.COM.
Distributed Object Management

Newsgroups: comp.std.c++
From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Zero-length structures and pointer comparisons
Organization: Computer Science, University of Melbourne, Australia
Date: Mon, 21 Dec 1992 12:59:46 GMT

(Sorry for the zillions of articles I seem to have posted today,
I'm just trying to keep up with maxtal ;-)

maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

>	Thats not the issue. It might be UNIMPLEMENTABLE on
>some architectures. In fact, == is UNIMPLEMENTABLE in general
                                                    ^^^^^^^^^^
>on the 386 in protected mode, given the sloppy definition
>of 'same object' in the ARM. Its quite possible on the 386
>to have two logical addresses which convert to the 
>same linear address, but NOT BE ABLE TO TELL THAT THIS IS THE CASE.
>Because to tell implies access to the LDT/GDT and the typical
>process is not able to read those tables. A special
>operating system function would be required to do this,
>and that would make C++ unimplementable on systems not
>having this function.

C++ implementations are not required to implement the correct
semantics for == in the general case, they only have to do so
for conforming programs. The compiler could ensure that
conforming programs never create two logical addresses which
map to the same linear address, and then the problem would not arise.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Newsgroups: comp.std.c++
From: hansen@myria.cs.umn.edu (David Hansen)
Subject: Re: Compiler should generate virtual destructors
Organization: University of Minnesota
Date: Mon, 4 Jan 1993 00:30:54 GMT

In article <C0Ayt4.263@fiu.edu>, feathers@serss0 (Michael Feathers) writes:
|> In article <1992Dec31.050150.28929@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
|> >I would like to propose that if a class has virtual functions,
|> >then any destructor generated by the compiler will be virtual
                        ^^^^^^^^^^^^^^^^^^^^^^^^^
|> >by default.
|> >
[...]

|> This would be a way in which a function within the source code would be
|> virtual without the keyword 'virtual' having been used on it or a function of
|> the same name in an inherited class.  That would bother me as a consistency 
|> issue.

I think you misread the original post.  Only the automagically generated 
destructors would be virtual by default.  If the programmer explicity
defined a destructor _without_ the virtual keyword, it would not be virtual
(unless _I_ misread the post  :).

|> 
|> >Disadvantage: might slow down destruction a little. Can be
|> >fixed by the programmer explicitly declaring a non-virtual
|> >destructor.
|> 
|> The only way to make something explicity non-virtual would be the absence
|> of the 'virtual' keyword, unless we add a new keyword <shudder>.

Again, see comment above.

					-=Dave
Newsgroups: comp.std.c++
From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Pointer comparisons
Organization: Computer Science, University of Melbourne, Australia
Date: Tue, 29 Dec 1992 19:13:45 GMT

eker@loria.fr (Steven Eker) writes:

>jss@lucid.com (Jerry Schwarz) writes:
>|> 
>|> 	A: Does the ARM currently require a1!=a2?  Apparently 
>|> 	   not, but I may have overlooked something.
>
>Has anyone noticed that slist_base::get() on p266 C++PL (2ed) assumes that
>pointers to different heap allocated objects compare unequal?

I hadn't noticed that one, but on page 238 in string::operator=() it
assumes that pointers to different strings compare unequal, whether
heap allocated, stack allocated, or statically allocated.

>Might this fail on a 486?

Yes, but only if the programmer had invoked some operating system memory
mapping function, in which case the consequences are on that programmer's
head. It is not a matter for the standard to worry about.

>There doesn't seem to be an easy fix for this example without maintaining
>a separate tail pointer.

Hopefully we can all agree that there is plenty of code around like these
two examples, which we don't want to break. Whatever wording is adpoted
by the standard, these examples should continue to work unmodified.

Note carefully, however, that these examples do *not* depend on pointers
to different *empty* objects comparing unequal.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
From: pnori@lsi-j.co.jp (Pochi NORIMATSU)
Newsgroups: comp.std.c++
Subject: Re: Ambiguity in member pointer declaration
Date: 21 Dec 92 07:04:55 GMT
	<1992Dec15.011359.17235@lucid.com>
	<PNORI.92Dec16132118@hyperion.lsi-j.co.jp>
	<GIROD.92Dec18142728@node_262d6.tele.nokia.fi>
Organization: LSI Japan Co. Ltd., Tokyo, Japan

In article <GIROD.92Dec18142728@node_262d6.tele.nokia.fi> girod@tele.nokia.fi (Marc Girod) writes:
>   Do you have a version of the ARM different than mine (1990, 
>   ISBN 0-201-51459-1...)?
>
>   In my book it reads in section 8.2.3, p 135:
>
>	   class-name :: * cv-qualifier-list<opt> D1
>
>   and class-name is just identifier (17.1 p 387)

I have two ARMs :-)

One is the same book as you have, and another is "Reprinted with
corrections May, 1992" version. In the reprinted book, class-name has
been replaced by complete-class-name.

BTW, the definition of ptr-operator in section 17.4 in the older book
is also says that a pointer to members starts with complete-class-name.
Don't you think its confusing?
--
Yasutoshi (Pochi) Norimatsu      | Never worry about theory as long as
pnori@lsi-j.co.jp                | the machinery does what it's supposed
LSI Japan Co. Ltd., Tokyo, JAPAN | to do.            -- R. A. Heinlein
Newsgroups: comp.std.c++
From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Variants
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Sun, 3 Jan 1993 04:47:02 GMT

Variants, Part II.
------------------

The 'type' clauses of a select statement specify an implict
variant:

	variant Num [float, complex, int] x;

	select(x)
	{
		type(double d) { ... }
		type(long l)   { ... }
		type(complex c) { ...}
	}

In this case the implicit variant is

	variant Implicit [double,long,complex];

This clearly indicates how variants interconvert,

	variant X [X1, X2] x;
	variant Y [Y1, Y2] y;

	Y y=x;

The conversion is well defined if each of X1 and X2 unambiguously
converts to either Y1 or Y2, where 'unambiguously converts' is
used in the same sense as the normal overload matching rules.

The select statement can have multiple arguments:

	variant V [V1, V2] v;
	variant W [W1, W2] w;

	select(v,w)
	{
		type(V1 *v1, W1 *w1) { ... }
		type(V2 *v2, W1 *w1) { ... }
		type(V1 *v1, W2 *w2) { ... }
		type(V2 *v2, W2 *w2) { ... }
	}

The select statement can have a 'default' (none-of-the-above)

	select(v)
	{
		type(V1 v1) { ... }
		type(...) { cout << "Type Not Handled"; }
	}

Where variants share a common base, it would be more usual
to do:

	class B;
	class D1 : B;
	class D2 : B;

	variant D [B,D1,D2] *d;

	select(d)
	{
		type(D1 *d1) { ...}  // special case
		type(B *b)   { ... } // default to base class
	}

Where dynamic downcasting is required, it can be constrained
to a one off function:

	D* downcast(B* b)
	{
		D *d;
		if (d=dynamic_cast<D1*>b);
		else if (d=dynamic_cast<D2*>b);
		else d=b;
		return d;
	}

allowing the downcast to be performed exactly once in one lexically
enclosed place, and thereafter guarranting secure access to
the required exact types.

(Note: this example requires variant assignment)

(Note 2: If you are a bit worried about the way the * symbol
got shifted about:

	variant V [V1, V2] *vp;
	variant pV [V1*, V2*] vp; // same as above??

show it makes sense and deduce a variant is not a type,
or wait for part III)

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.std.c++
From: jss@lucid.com (Jerry Schwarz)
Subject: Re: Pointer comparisons
Reply-To: jss@lucid.com (Jerry Schwarz)
Organization: Lucid, Inc.
Date: Wed, 23 Dec 92 18:24:56 GMT

Jim Adcock is advocating that under some circumstances it
is ok for a compiler to put two A objects at the same location.

His example is

|> class A {};
|> 
|> class B : public A
|> {
|> public:
|> 	A a;	
|> };
|> 

	B b ;

Where he claims it is ok for b.a and (B&)a to compare equal.

I don't agree, but I'm wondering exactly what criteria he is applying.
Does anything go for A's.  E.g.

	void f() {
	    A a1, a2 ;  // can &a1==&a2 
	    ... ; 
        }

Is it only ok for "empty" classes? How about 

	struct D { int i; int j ; } ;

	void f() {
	    D d1, d2 ;
	    ... d1.i ... d2.j ...  // never use d1.j or d2.i 
            }

Can &d1==&d2.

  -- Jerry Schwarz
Newsgroups: comp.std.c++