From: jimad@microsoft.com (Jim Adcock)
Subject: Re: pointer comparisons
Date: 06 Jan 93 20:16:47 GMT
Organization: Microsoft Corporation

In article <1993Jan5.222300.29535@lucid.com> jss@lucid.com (Jerry Schwarz) writes:
|I completely disagree with the premise. Maybe we are using 
|"object" in different senses.  An important "attribute" of
|an object (defined as a region of storage by both the C 
|standard and the ARM) is its relationship to other regions
|of storage.

Whether or not people agree with a particular set of premises it might
be nice to start with at least *one* explicitly stated set of premises
and terminology that remains consistent with the clearly stated requirements
of the ARM, and which remains relatively consistent with most parts of
most implementations of the ARM.

|To take a simple example
|
|	int a[10];
|
|It is an important attribute of a[2] that it is the 3rd
|subobject of a 10 element array.  
|
|struct S { int i ; int j ; } s ;
|
|It is an important attribute of s.j that it is the "j" subobject
|of s.   

I wouldn't call either of these things "subobjects."  I would call then
elements and members respectively, and would require that elements and
members are indeed "objects" which follow all the rules of "objects"
whatever those rules might be.  I don't think this is much of an issue --
excepting deciding on what rules all "objects" must obey.  A bigger
issue seems to be whether or not inherited base parts represent 
"objects" in their own rights, or are they not "objects."  If
they are "objects" then they must follow all the rules that 
[someone someday] establishes for "objects" otherwise they could follow
some other set of rules established for "base parts" or whatever you
want to call them.  My claim would be that the [unstated] rules for
base parts as implied by ARM and common implementations are sufficiently
different from other "objects" that such can't reasonably be considered
as part of the "object" rules.  At least I can't think of such a set
of consistent rules.  If you can come up with a consistent set of rules
that match ARM requirements and most of most implementations -- hey,
then go for it!

|If you prefer to use a word other than "subobject" to describe
|this relationship, I suppose you can do so.  But however you
|describe it, it is an important concept in the semantics of C++.

Agreed, its just that those base parts don't necessarily follow
all the rules of "objects"

|Perhaps you disagree that a[2] or s.j are "objects"?  If so
|then I think you should reconsider your terminology.  "object"
|is the term used throughout the C standard and ARM for this
|concept. 

I agree that elements and members are objects.  Base parts
are neither elements nor members, but base parts can have
elements and members.  I do not consider a base part in
itself to be an object.

|And a "base subobject" bears an analogous relationship to the
|containing object(s).  

I disagree.  I consider the analogy to be sufficiently weak 
that I don't think a consistent set of rules can be developed
for both base parts and other objects that reasonably captures
the behavior of both categories.

|A virtual function call (as I noted in
|another item I posted recently) requires taking a base object
|and finding the appropriate derived object containing the base
|object.  This can't be done based solely on the contents of
|the base object.  

Note that this is considerably different behavior than built-in
objects, "C" struct objects, standalone C++ objects, member objects, 
and element objects.  Thus I believe these base parts do not 
represent "objects" but rather fall into a different category of thingees.

|The data members of a class are also subobjects according to
|my understanding.  You're even disallowing that?  

I don't think that's anyone's intent.

||> 	Is the issue not simple: either we waste bytes
||> to obtain object identity for subobjects or we dont.
||> 
|
|I can phrase begging questions too. Either we implement the
|language correctly or we fudge, save a byte and hope nobody
|notices. 

How can anyone implement the language "correctly" if you are
going to define "correctness" in terms of your undefined requirements
that neither you, ARM, nor the ANSI-C base document calls out?

If an implementation does not contradict clearly stated requirements of
the  base documents, then the language HAS been implemented correctly.  
If this is unacceptable to you, then write a up a clear, complete, 
set of rules of what you say objects are and aren't and what properties
they do have and don't have *in the language* and get the
rest of the C++ committee to buy-off on your definitions.
Then implementations can implement these agreed-upon set of rules
in the famous "as-if" manner, and no one can complain.  Until
then we simply are arguing for our particular favorite *implementation*
[NOT *LANGUAGE*] and arguing against the other guy's implementation.

|Apparently the issue isn't simple.  There is a fundamental
|disagreement about the semantics of C++.  If that disagreement
|is resolved it will tell us what is a legal implementation.
|We can use the consequences for storage layout and sizes as
|a criterion for determining the semantics, but it can't be
|the sole criterion.

We're not even yet to the stage of fundamental disagreement,
because neither camp[s] has clearly defined what they're talking
about.  Many people are even clear yet that they're being
unclear.  Once there are clear statements of what the various
positions are, *then* the possibility exists of working through
any disagreement, and reaching a workable compromise.