From 8357848251420061051
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,e94695845965b249
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 1992-12-08 11:55:15 PST
Path: sparky!uunet!tymix!tardis!olivea!spool.mu.edu!sgiblab!munnari.oz.au!metro!extro.ucc.su.OZ.AU!maxtal
From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Newsgroups: comp.std.c++
Subject: Re: Zero-length structures and pointer comparisons
Message-ID: <1992Dec8.193218.13165@ucc.su.OZ.AU>
Date: 8 Dec 92 19:32:18 GMT
References: <1992Dec1.072440.824@jyu.fi> <1992Dec02.212336.26703@microsoft.com> <1992Dec4.093044.16823@jyu.fi>
Sender: news@ucc.su.OZ.AU
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Lines: 216
Nntp-Posting-Host: extro.ucc.su.oz.au

In article <1992Dec4.093044.16823@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes:
also Jim Adcock and myself ..
>> ...
>>use of them.  You cannot gratuitously make changes to the base language
>>now without darned good justification -- which YOU have not established.
>
>I think the example showed extremely bad hacking style, depending critically
>on the behaviour of one specific compiler, 

	Worse, it depended on one memory model of the compiler.

>while the same thing could be achieved
>in a fully standard and portable way with minimal if any performance penalty.

	I thought I did explain this statement is not correct. Unless
you are an 8086 assembler expert as I am, please take my word for it,
because I dont want to bother actually writing the 8086 code to show.
(I want to give up 8086 real mode assembler coding!)

>I don't think that the C++ community as a whole has an obligation to assure
>the continued legality of such bags of dirty tricks.

	I admitted the example I gave was silly, it was all I could think
of quickly. The point is that in the absense of prohibition, and
or specific wording 'implementation defined' it is indeterminate
which programs---hacked or not--would break.

	Here is another example: Because the 8086 is limited to
1M address space the addresses FFF0:0100 and 0000:0000 are equal.
This 'segment wraparound' property is actually used by many 8086
programmers, in fact, there is a specific operating system 'call'
that uses this fact (a hang over from CP/M actually).

	As long as data structures are aligned on 16 byte boundaries,
it is quite normal to adjust segment registers so you can scan two
arrays in parallel using a single 16 bit offset register. This
might be a hack, it is certainly machine specific, but recall
one of the design aims of C was to allow operating system design,
and a close correspondence to the hardware...even if that hardware
is 'not so good'. 

	It *is* normal to try to write really fast code on the 8086,
at the expense of hacks, after all the processor itself is a hack,
but there are lots and lots of them, and non-academic programmers
have to make a living.

	If we were designing a 'from scratch' language it wouldn't be
C++, it would be Eiffel :-)

>>You still seem to be confusing the issue of conforming programs verses 
>>strictly conforming programs.  A conforming PC program can use large
>> ...
>>for segment and offset variables.  Prior to these language extensions, 
>>such comparisons HAD to be done by hack because their was no language
>>support for them.  Now you proprse to require C++ implementaions break
>>these existant conforming C programs.
>                          ^^^^
>
>Please don't mix up C into this, C++ _is_ a separate language.

	Not completely. C compatibility is one of the most important
issues taken into consideration. Breaking it is considered only if there
are strong arguments. Breaking prior versions of C++ is less of a problem,
there isn't a prior standard to break, after all.

>(I don't know about the drafts of the ANSI committee, 
>but at least the ARM does not
>use any terminology like 'conforming' and 'strictly conforming'.)

	It doesnt have to. Jim explained what the implications are to
me, and if I have it right a strictly conforming program should
work on any compiler//machine, i.e. be portable, but a merely
conforming one might be quite system specific.

	Non-strictness is mandatory for some programs, sometimes
even non-conforming is needed. For example, no Windows program
can possibly conform to C++ specs, if only because Windows
programs have a WinMain entry and not a main entry. But there
are other reasons, one being that the C/C++ linkage/memory
model concepts are obsolete and cant cope with the requirements
of modern systems. For example, Windows supports dynamic
linkage, and to use it you have to nominate *in the language*
which functions are exported. Borland C++ therefore has
a _export keyword. Similarly, on any 80x86 system there are
various memory models and it is sometimes necessary to
nominate the type of pointer being used: _far for example.

	This is inevitable in any language purporting to
support access to the hardware on various machines.	

>So you say that most C++ compilers for the PC used to be more or less broken
>(could not implement the full language), and programmers were therefore forced
>to dirty tricks as work-arounds?  Could you finally give a short concrete code example?

	This is not the point. Non-strictly conforming means that
where 'implementation defined' is specified in the manual, the programmer
has utilised a specific implementations features. Such a program
wont run on another platform, but then an embedded real time system
designed to control specific hardware wont do that anyhow.
>
>>Maintain a total ordering over a OODBMS!!??
>
>Please calm down 
>(your throat will get sore if you use so many exclamation signs)
>and try not to confuse things.  

	Markku, having the greatest respect for yourself and Jim I should
point out that it is part of Jim's style to use many !!??** marks.
I dont mind if he shouts sometimes, I wont go deaf listening on the net :-)

>C++ as a language does not directly support an OODBMS.  

	But many people want to use it for that.

>C++ pointers are memory pointers, and object references within an OODBMS
>are a different thing (you will need a stronger and cleaner concept of object
>identity there anyway).  I'll try to explain:
>
>As long as we have C++ objects, i.e. in memory, their addresses (or at least the
>valid pointer values to access them) _must_ stay constant, because C++ has no
>means to automatically track down and modify all pointers to an object.

	It doesnt need to have. There could be a silent system 
in the background doing this. For example, in Windows-real mode,
exactly this happens. The programmer is required to specifically
call a lock function on a handle to obtain a pointer, and unlock it
afterwards.

>If the contents of some object are copied to or from the DB, that does not
>change or complicate the situation.  On the other hand, if some C++ object is deleted
>after having been copied to the DB, and the DB object is later restored into memory,
>it will be a _new_ C++ object.  

	Thats *your* idea. But if someone proposed some implementation
specific scheme whereby in *their* C++ implementation, a pointer
was *not* a machine address but a handle it might still be
a conforming but not strictly conforming program.

>
>>Again, seems clear to me that using a total ordering is simply a
>>un*x-memory model hack, and should be treated as such.  If *you* want
>> ...
>
>Sorry, but IMO it's you who have been furiously defending hacks, not I.

	Whats a hack is clearly relative to your point of view :-)

>Perhaps there is this misunderstanding:  you think that the requirement
>of total ordering for pointers implies a linear address model.

	No I think Jim is saying that existing software that uses
implementation defined semantics which happen not to be a total order
would be broken.

>No, we don't require that the ordering should directly map into physical order,
>it's just as fine if a pointer consists of base and segment and relocation and index
>or whatever.  Punning would do, i.e. treating the pointer as if it were an integer value.

	This is not necessarily the case. For example,
there is a phenomena called aliasing, it already causes problems for
the == and != operators. Two equal linear addresses might have several
different logical addresses. And two equal linear addresses
might be two different physical addresses .. in the same program
even at different times (virtual memory).

	On the other hand two unequal linear addresses might always
refer to the same memory. C++ already requires pointers to the same
object to compare equal, and this is a heavy constraint. A read-write
and read-only segment may be aliased, and two pointers using these
different segments to access the same object will not compare equal.
Computing the linear addresses is not possible, the user codes
are prevented from doing that.

	Furthermore, 386 selectors have a few bits in them relating
to access privileges of the requestor and nothing to do with the actual
segment requested. So even comparison for equality is problematic,
a total ordering requirement could be a bit messy to implement.

>However, the ARM does not require implementations to provide an integral type
>that is sufficient to store an arbitrary pointer.

	That is good, the 386 has 48 bit pointers but only 32 bit registers.
>
>One obvious case where a total order of pointers would be nice to depend on
>are (large) collections of pointers -- I think Andrew Koenig mentioned this
>many submissions ago.  With total order, you can organise such collections
>e.g. so that binary search can be used, requiring O(log N) time;
>otherwise you are stuck with linear search and O(N) time.

	Indeed there are good arguments for total ordering.
There are also good arguments in favour of pointers being
totally abstract entities on which no operations at all are allowed
except accessing the object to which they point.

	An operating system kernel for the 386 might well have
physical, linear, and logical addresses, and indeed one of its major
purposes might be to manage memory. Such a program would be
totally ham-strung by a total ordering requirement since memory
on modern architectures just isnt organised that way. In fact,
such a program would probably have to be non-conforming because it could
not meet the == and != requirements. Should the OS programmer
really be forced to write the OS in assembler to defeat overly
strict C++ rules based on invalid assumptions about machine
architectures?

	Summary: C and C++ are designed for writing both portable
and non-portable software. This always leads to some undesirable
tradeoffs. Lack of total ordering makes OS writing easier for
specific implementations, whereas total ordering makes portable
software easier. Who can decide which is more important?

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------


