HDTenEightyP/NetNews huggingface dataset:
From: jss@lucid.com (Jerry Schwarz)
Subject: Re: Pointer comparisons
Reply-To: jss@lucid.com (Jerry Schwarz)
Organization: Lucid, Inc.
Date: Tue, 29 Dec 92 04:28:28 GMT

jss:
|> ||Does anything go for A's.  E.g.
|> ||
|> ||	void f() {
|> ||	    A a1, a2 ;  // can &a1==&a2 
|> ||	    ... ; 
|> ||        }
|> |

jimad:
|> Let me restate the question as an answer.
|> 
|> Does the ARM anywhere say that two pointers of the same type to two different 
|> objects of the same type not in the same array must compare not equal?  
|> 
|> If not then what does the ARM say of any such comparison?

As far as I can tell, except for the special cases enumerated in
5.9 and some hints about the behavior of new, the ARM 
never requires two pointers to compare unequal.  I believe this is 
an oversight and should be corrected in the standard when it emerges. 
I believe the intention has always been that distinct objects have
distinct addresses and I belive that the final standard should say so.

What should x3j16/wg21 do? One alternative would be to leave
the words unchanged.  (I think this is Jim's position,
but I'm not sure.)  This apparently allows &a1==&a2 in the above,
and in other cases as well.  If the committee does this, it
should do it explicitly after due consideration and not simply
allow the status quo to remain by default.

Another possibility which has been proposed here recently (sorry
I don't remember by whom)  is to add something like "two pointers to
T (where T is an object type) compare equal if and only if they point
to the same object".   This seems a useful rule to me.  Note that
it makes no distinctions between "empty" and "non-empty"  classes.
An alternative might be to apply this rule except for "empty"
classes.  
	
So there really several related questions about this example.

	A: Does the ARM currently require a1!=a2?  Apparently 
	   not, but I may have overlooked something.

	B: What do existing compilers do.   How common is the
	   code that might be affected if the compiler was
	   changed to do something else.  How much existing
           code currently assumes that a1!=a2.

	D: Should the standard when it emerges require a1!=a2.
	   I think yes, and am concerned with exactly how to
	   word this requirement.  There are many potential
	   examples and I would greatly prefer a general rule
	   to an enumeration of cases.

Knowing the answers to A and B for this and similar cases
might influence my opinion  on C, but I am not prepared in advance
to state a rule that would allow you to derive my opinion of C
from the answers to A and B.
 
   -- Jerry Schwarz
 
Newsgroups: comp.std.c++
From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Pointer comparisons
Date: 19 Dec 92 00:18:51 GMT
Organization: Microsoft Corporation

In article <1992Dec17.151642.9954@bcrka451.bnr.ca> sjm@bcrki65.bnr.ca (Stuart MacMartin) writes:
|>4) If two pointers p and q (of the same type) are obtained through
|>   sequences of "normal" operations, then
|>
|>      p == q   <==>   p and q point to the same object
|
|I could not find this statement in the current wording.  Is there a 
|reason why the current wording is weaker than this?

Again, a simple counterexample is as follows:

#include <stdio.h>

class A {};

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

main()
{
	B b;

	A* pb = &b;
	A* pa = &(b.a);

	if (pb == pa)
		printf("equality of two legal ptrs of the same type pointing"
		"at different objects");

	return 0;
}

Again, my claim is that this is perfectly legal C++ code, which is commonly
implemented in some C++ compilers such that the equality test does
test true.  On the contrary, for the test to not prove true would
mean that the empty base class part has to be implemented by the compiler
using gratuitous padding, and gratuitous padding is an anathema to
traditional C/C++ implementation.  
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: Fri, 25 Dec 1992 16:42:16 GMT

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

>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.

*In general* this is true, but we are not talking about the general case.
All that is required is that it be true for conformant C++ programs.
This does not require checking whether segment aliases exist, it just requires
ensuring that they won't occur for conformant C++ programs.

>>>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.

Yes, you are correct. I retract that statement.

-- 
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: jimad@microsoft.com (Jim Adcock)
Subject: Re: Pointer comparisons
Date: 24 Dec 92 20:08:40 GMT
Organization: Microsoft Corporation

In article <1992Dec22.140212.12579@bcrka451.bnr.ca> sjm@bcrki65.bnr.ca (Stuart MacMartin) writes:
|2.  Perhaps there is a philosophical argument that might resolve this issue.
|    If two objects have the same interface but no state (or constant state), and
|    they have the same lifetime, are they in fact the same object?  Or, perhaps,
|    can they be treated as if they are the same object?

Here's a simple counterexample. b and b.a are clearly different objects.
They have different type, and they respond differently to a given method
call.  

HOWEVER, they can both be legally used to initialized an A*, and
in which case the pointers compare equal, and the two different objects
THEN respond the same to a given method.


#include <iostream.h>

class A
{
public:
	static void print() { cout << "A\n"; }
};

class B : public A
{
public:
	A a;
	static void print() { cout << "B\n"; }
};

main()
{
	B b;
	b.print();
	b.a.print();

	A* pb = &b;
	A* pa = &(b.a);

	if (pa == pb)
		cout << "addresses match\n";
	else
		cout << "addresses don't match\n";

	pb->print();
	pa->print();

	return 0;	
}
From: jnw@shades.cis.ufl.edu (Joseph N. Wilson)
Newsgroups: comp.std.c++
Subject: templatized typedef?
Date: 22 Dec 92 20:45:07 GMT
Reply-To: jnw@shades.cis.ufl.edu (Joseph N. Wilson)
Organization: University of Florida CIS dept.

Please forgive me if this is old ground for this group.

CFront 3.0.1 does not let me do the following:

	template <class T>
	class C{ ... };

	template <class S>
	typedef C<S>  D;


The reason I'd like to do this is to be able to rename (using typedef)
a number of classes.  I thought this would be a clean way to rename
the template classes if it were supported.  I had a suspicion it might not
be supported right from the start.

Anyway, here's my question:

Is what I'm trying to do above _standard_ C++, or is it a fringe interpretation.
I figured because my typedef is a decl-specifier introducing a class-name,
that it should be a valid class declaration, thus the ARM should be satisfied
on page 342.  Is my reasoning faulty?  What do you gurus say?

Joe Wilson
(jnw@cis.ufl.edu)

P.S. CFront complains saying "D: only static data class members may be
parameterized."  I have difficulty interpreting this message in the context
above.
From: feathers@serss0 (Michael Feathers)
Newsgroups: comp.std.c++
Subject: Re: Compiler should generate virtual destructors
Date: 4 Jan 93 00:03:04 GMT
Organization: Florida International University, Miami

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.
>
>(The suggestion was first read by me in a paper of Markku Sakkinen,
>who claims it was not his idea originally either.)
>
>Advantages: much safer, ensures correct deletion of objects
>by default.  Removes a source of bugs. Removes the reminder
>that its wise to do this from the FAQ.

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.

>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>.

If the destructor is going to be made virtual by that rule, there is no
need to declare it virtual.  But we can not make it explicitly non-virtual
unless the virtual keyword is an option.


Michael Feathers  [feathers@fiu.edu]      main () { main (); }
Newsgroups: comp.std.c++,comp.std.c
From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Question about sizeof in C/C++.
Date: 24 Dec 92 00:15:40 GMT
Organization: Microsoft Corporation

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 chosen such that k is greater
than or equal to zero [true since k unsigned], and k is less than or equal 
to the number of elements in the array pointed-to by ps, assuming ps 
points at a valid array of type Something, and in C++ assuming that 
that operator& isn't user-defined on struct [class] Something....

Did I miss anything?
Newsgroups: comp.std.c++
From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Pointer comparisons
Date: 30 Dec 92 18:30:53 GMT
Organization: Microsoft Corporation

In article <9236101.2804@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>The definition of objects being "the same" is not clear.

Exactly.  Also, the definition of "same type" and "pointer" is not
clear....

Newsgroups: comp.std.c++
From: dpg@extro.ucc.su.OZ.AU (D P Gilbert)
Subject: Re: Compiler should generate virtual destructors
Organization: Sydney University Computing Service, Sydney, NSW, Australia
Date: Sun, 3 Jan 1993 12:06:25 GMT

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

>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'?
> ......

How about a new keyword "__pure" to
	1)	prefix "class" in a class definition to stop automagic
		constructor + assignment generation ++
	2)	prefix "virtual" in a pure virtual function
		declaration to get rid of the "=0" hack
	3)	waste some of the compiler implementor's name space
		(rather the the compiler user's name space). The
		user can #define pure __pure if it causes no problem


Doug Gilbert
Newsgroups: comp.std.c++
From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Must derived class reserve space for an empty base class?
Date: 24 Dec 92 20:23:39 GMT
Organization: Microsoft Corporation

In article <85744@ut-emx.uucp> jamshid@ut-emx.uucp (Jamshid Afshar) writes:
|The fact the following idiom works under all current C++
|implementations, and that it will probably continue to work no matter
|what ANSI says, is what most worries me and why I originally posted
|this question.  Programmers will continue to do things like
|	class Register {
|	   Set<Register*> alive;
|	protected:
|	   Register() { alive += this; }
|	   virtual ~Register() { alive -= this; }
|	   static void foo();  // do something to all registered objects
|	};
|
|If a special-case rule is not added making the above safe on *any* C++
|implementation, I hope more C++ literature will point out the fact
|that the above idiom is incorrect.  

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.  In the absence of evidence, I will hypothesize
the opposite, namely that your class DOESN'T work under all current
C++ implementations.

Below find an example that frequently catches programmers off guard.
Again, C++ pointers DO NOT model any notion of object identity.  If you
want your objects to maintain a notion of object identity [A good
idea, IMHO] then you must explicitly GIVE your objects a notion of object
identity.  C++ comes with no such notion built-in.

#include <iostream.h>

class A { char bsPadding; };
class B : public A {};
class C : public A {};
class D : public B, public C {};

main()
{
	D d;

	B* pb = &d;
	C* pc = &d;
	A* pa1 = pb; 
	A* pa2 = pc; 

	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";

	return 0;
};

Newsgroups: comp.std.c++
From: pkt@lpi.liant.com (Scott Turner)
Subject: Re: Pointer comparisons
Organization: Liant Software Corporation
Date: Mon, 21 Dec 1992 18:48:46 GMT

In article <1992Dec18.202539.22728@ucc.su.OZ.AU>, maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
> >"the result depends on the relative positions ... in the address
> >space."  What does this mean?  
> 
> 	This means that the committee has committed a grave error.
> Too many Unix people. The ARM also commits this error in
> assuming the existence of *an* address space. 

Implicit smiley detected :-)  It actually means that the committee adopted
the ARM's text as its base document and as the foundation of its working
paper.  The committee has not yet addressed the shortcomings of the ARM's
5.9 and 5.10.

In article <18188@autodesk.COM> larsn@Autodesk.COM (Lars Nyman) writes:

> ARM specifies what a comparison of two pointers to objects should return
> IF:
> 	- the objects are the same
> 	- the objects are non-static members of same object
> 	- the objects are elements of the same array
> 
> Otherwise, the pointer comparison is implementation dependent.
>
> 
> So, if I have pointers to two different objects the result of comparing
> them is implementation defined !?!
> Thus, I cannot even trust that a '!=' test will return 1 for two objects
> that are not the same !
> 
> This must surely be wrong... can somebody, please, correct me and explain
> what I'm overlooking.

This problem has the same explanation.  5.9 and 5.10 need work
before they're suitable for a standard.  I avoid them when trying
to understand the meaning of pointer comparison, and get out my C standard.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com
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: Mon, 21 Dec 1992 19:17:55 GMT

daniel@cse.ucsc.edu (Daniel R. Edelson) writes:

>There's also a problem regarding inline functions.
>Specifically, under common file-based C++ implementations, 
>the address of an inline function  can vary between
>compilation units. Thus, the requirement from
>Ansi C (Sec 3.3.9)
>	``If two pointers to function types ... both point to
>	the same function, they compare equal.''
>is false under common C++ implementations.

Actually, these implementations are correct. Inline non-member functions have
internal linkage, and thus an inline function in one compilation unit
is a different function to even a lexically identical inline function in
a different compilation unit. (Inline member functions however are a
whole different can of worms.)

Does ANSI C require that pointers to different functions
will compare unequal? If so, it is not the common C++ implementations
that are the difficulty, it is the more sophisticated C++ implementations
(such as Borland C++ with the "Smart Inlines" flag enabled) that use
smart linkers or other techniques to avoid generating multiple copies
of inline functions.

Personally I believe that the default internal linkage for inline
non-member functions was a mistake, brought about by letting the
original implementation dictate too strongly the semantics of the
language. Even if it is perhaps too late to change this, the ANSI C++
standard should definitely not require that pointers to different
functions compare unequal, because that would prevent a useful
optimization, with no real gain. It should be enough to require
that if f and g are function pointers of the same type for which
f==g, then (*f)(...) has the same effect as (*g)(...).

-- 
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: eker@loria.fr (Steven Eker)
Newsgroups: comp.std.c++
Subject: Re: Pointer comparisons
Date: 29 Dec 92 15:38:04 GMT
Organization: CRIN (CNRS) Nancy - INRIA Lorraine

In article <1992Dec29.042828.27808@lucid.com>, jss@lucid.com (Jerry Schwarz) writes:
[stuff deleted]
|> 	
|> So there really several related questions about this example.
|> 
|> 	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?
Might this fail on a 486?

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

Steven
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: Fri, 25 Dec 1992 15:16:59 GMT

pkt@lpi.liant.com (Scott Turner) writes:

>In article <1992Dec19.001851.22116@microsoft.com>, jimad@microsoft.com (Jim Adcock) writes:
>> On the contrary, for the test to not prove true would
>> mean that the empty base class part has to be implemented by the compiler
>> using gratuitous padding, and gratuitous padding is an anathema to
>> traditional C/C++ implementation.  
>
>"Gratuitous" is your own judgment.  Some of us disagree.
>Moreover, such padding is in the C++ tradition.  

One of the most important principles of C was that if you didn't use a
feature, you shouldn't have to pay for it. This principle was carried
through to C++. On the topic "Design Notes", Bjarne Stroustrup wrote
	"Features that would incur run-time or memory overheads even when
	not use were avoided" [C++PL, 2nd Ed. pg 3].

As a feature, padding empty base classes fits this description exactly.
It has a very significant memory overhead, especially if there
are multiple levels of derivation involved. Such padding could easily
double (or worse!) the memory required for classes derived from
abstract base classes.

Stroustrup goes on to say
	"For example, ideas that would make it necessary to
	store ``housekeeping information'' in every object
	were rejected; if a user declares a structure consisting
	of two 16-bit quantities, that structure will fit into
	a 32-bit register" [Ibid.]

In the case of deriving from empty structures, it is absolutely TRIVIAL
to insert padding yourself *IF* you really need the addresses to be different.
If such padding were to be inserted by the compiler, then there would be
NO WAY to turn this feature off in cases where you weren't using it.

To force implementations to insert such padding would go against one of
the strongest guiding design principles for both C and C++.

As a final point, I believe that requiring padding when deriving from
abstract base classes would strongly discourage their use, for efficiency
reasons. This would be a very bad thing IMHO, because abstract base classes
are a very important design tool, and if the design can't be represented
directly in the programming language, then there is a significant cost
in terms of productivity and maintainability.

The concise OED defines "gratuitous" as (amoung other things)
"uncalled for, unwarranted". Given the above arguments, I would
definitely describe inserting padding when deriving from empty
classes as "unwarranted". Furthermore, if the programmer didn't
ask for the padding and didn't want it, how could you say it was
anything other than "uncalled for"?

-- 
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++