From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Pointer comparisons
Date: 24 Dec 92 20:02:01 GMT
Organization: Microsoft Corporation

In article <1992Dec23.182456.17185@lucid.com> jss@lucid.com (Jerry Schwarz) writes:
|Jim Adcock is advocating that under some circumstances it
|is ok for a compiler to put two A objects at the same location.

NO I AM NOT SO ADVOCATING!  I am saying it is legal for a compiler
to put objects wherever it so likes unless it doesn't explicitly 
and clearly violate a requirement of the ARM.

Note that my example DOES NOT put two A objects at the same location.
Rather it puts an A object at the start of a B object such that the
A object has the same starting address as the B object.  My claim is
that from "C" history this is nothing new.  We EXPECT that the first
member of a structure has the same starting address as the structure.
We DO NOT EXPECT a compiler to gratuitously add padding at the
start of a structure.  Any padding in a structure comes between 
members of the structure, or at the end of a structure so that array
elements come out aligned.

|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 assume you make an accidental typo.  On the contrary what I said it is 
okay for &(b.a) and ((A*)&b) to compare equal.  It is okay because ARM
says that unless the ARM states otherwise all pointer comparisons are
*implementation defined*

|I don't agree, but I'm wondering exactly what criteria he is applying.

The ARM.  Show me a statement in the ARM that clearly contradicts this
behavior.   If no statement clearly contradicts this possible implementation,
the implementation stands, because the ARM *explicitly* states that the
implementation stands unless called out otherwise.

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

Of course not!  ARM clearly requires members within a labeled public/private/
protected section to be ordered with later members having "higher" addresses.

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

ARM:

"Two pointers to the same object compare equal.  If two pointers
point to nonstatic members of the same object, the pointer to the later
declared member compares higher provided the two members not separated
by an *access-specifier* label ($r.11.1) and provided their class is not
a union.  If two pointers point to nonstatic members of the same
object separated by an *access-specifier* label ($r.11.1) the result is
undefined.  If two pointers point to data members of the same union,
they compare equal.  If two pointers point to elements of the same
array or one beyond the end of the array, the pointer to the object
with the higher subscript compares higher.  Other pointer comparisons
are implementation dependent."

Is your questioned pointer comparison listed here?  No.

Therefore it is EXPLICITLY declared *implementation dependent* by the ARM.

Likewise with my first example that you questioned.
Newsgroups: comp.std.c++