[comp.lang.eiffel] Storing C pointers in Eiffel code

rick@tetrauk.UUCP (Rick Jones) (11/30/90)

In another posting I show some examples of C code interfacing to Eiffel.  While
doing this work, I realised that there are problems of portability of Eiffel
code where external C addresses are involved.

It is current practice in Eiffel to treat C addresses as INTEGER types, since
there is no basic type which actually represents an arbitrary reference.  That
this works at all actually relies on the fact that long ints and pointers are
the same size and interchangeable.  This is not guaranteed by C!  Such Eiffel
source will NOT be portable to an implementation where the underlying C
representation does not allow interchange between pointers and integers.

Implementing Eiffel on an architecture where pointers and ints cannot be
interchanged should be perfectly feasible in a way which is transparent to
Eiffel source, with the exception of the representation of C addresses.  For
long term portability, Eiffel requires a basic data type which is used solely
as an external reference.

With a C implementation and external interface, support for anonymous data
pointers is simple, since it is supported in the form of void* (ANSI) or
char* (K&R).  All that is needed is a name which Eiffel treats as such a data
type, and does not allow any operations on, apart from assignment to another
entity of the same type, or passing to and from external routines.

Perhaps EXTERN would be appropriate, being borrowed from C (although with
different meaning).  It is also associated with the keyword "external" which
declares external routines.  The generated C code should pass these values to
C functions cast as (void *) or (char *) depending on the C compilation
environment.

Addresses of Eiffel entities passed in the form "@name" should also be cast to
(void *) or (char *) in the C code.  There is a problem with addresses of
routines, since C does not support the equivalent of "void *" for function
pointers.  It is also MORE likely that function pointers will not be
interchangeable with integers than is the case with data pointers.  The
solution most likely to be portable is to cast routine addresses as pointers to
functions which return an int.

This means that EXTERN could not be relied on to hold the address of a routine,
either an Eiffel one or an external C one.  However, I cannot think of a case
where a routine address would need to be held as an entity within Eiffel code.
On this basis there is probably no justification for a "routine address" data
type.  Perhaps other Eiffel users would care to comment?

Interfaces to C will be a vital part of any serious Eiffel application for a
long time to come (until we have an OS written in Eiffel perhaps?).  Hardware
architectures will change well before that, raising these sorts of problems.
It is vital that Eiffel source does not depend on any specific quirk of current
hardware;  the use of INTEGER for external addresses is just such a dependency,
which can only be solved by introducing a special data type.

Comments from other Eiffel users, and especially ISE, welcome!  In particular,
what would be the best name for the EXTERN type, or what should NOT be used
(because you've already used it as a variable or class name, perhaps :-)?


BTW, where is NICE?  Apart from an announcement that it now officially exists,
I've heard nothing.  The announcement said that all attendees of the California
and Paris initial meetings would be contacted directly.  I was at the Paris
meeting ...

-- 
Rick Jones
Tetra Ltd.  Maidenhead, 	Was it something important?  Maybe not
Berks, UK			What was it you wanted?  Tell me again I forgot
rick@tetrauk.uucp					-- Bob Dylan

richieb@bony1.uucp (Richard Bielak) (12/06/90)

In article <1039@tetrauk.UUCP> rick@tetrauk.UUCP (Rick Jones) writes:
>
>In another posting I show some examples of C code interfacing to Eiffel.  While
>doing this work, I realised that there are problems of portability of Eiffel
>code where external C addresses are involved.
>

[... stuff about using INTEGER type to store addresses and how
     non-portable that is
...]

What about using the BITS type to store address. Then you could have
code like this:


      some_address : BITS my_machines_address_size_in_bits;
                                
                                 ^
                                 | this is constant of course

...richie



-- 
+----------------------------------------------------------------------------+
|| Richie Bielak  (212)-815-3072      |  If a thousand people say a foolish  |
|| USENET:        richieb@bony.com    |  thing, it's still a foolish thing.  |
+----------------------------------------------------------------------------+

rick@tetrauk.UUCP (Rick Jones) (12/06/90)

|In article <1039@tetrauk.UUCP> rick@tetrauk.UUCP I wrote:
|>
|>In another posting I show some examples of C code interfacing to Eiffel.  While
|>doing this work, I realised that there are problems of portability of Eiffel
|>code where external C addresses are involved.
|>
|n article <1990Dec5.171420.22935@bony1.uucp> richieb@bony1.UUCP (Richard Bielak) writes:
|
|What about using the BITS type to store address. Then you could have
|code like this:
|
|
|      some_address : BITS my_machines_address_size_in_bits;
|                                
|                                 ^
|                                 | this is constant of course

Nice try for a quick solution in the current language, but the trouble is it's
probably even LESS portable than using INTEGER!  The point is that I want the
same Eiffel source to compile and run on any system, ideally such that the C
package can be ported to a different architecture and still operate correctly.
This is perfectly possible if DATUM and the associated manipulations are
properly declared and used as a union in the C runtime code.

The last thing I want the Eiffel source to depend on is the ACTUAL size of any
machine's address word.

I really don't see how it can be done without a specific Eiffel datatype.

-- 
Rick Jones
Tetra Ltd.  Maidenhead, 	Was it something important?  Maybe not
Berks, UK			What was it you wanted?  Tell me again I forgot
rick@tetrauk.uucp					-- Bob Dylan

nhr@eng.cam.ac.uk (Neil Russell) (12/12/90)

How about using a builtin type ADDRESS (a al Modula-2).  In modula-2
the type ADDRESS is compatible with any pointer type (analogously
class type in Eiffel), and in addition to assignment, arithmetic may be
performed on values of type ADDRESS permitting the construction of
memory managers.  This latter feature may not be suitable/relevant
in the Eiffel context, where memory management (garbage collection) is
hidden from the Eiffel programmer.  Portability considerations aside,
the attraction of having a specific type (as opposed to integer or
`bits N') is clarity.

A not totally unrelated defficiency of Eiffel is the inability to
define formal enumeration types -- entities representing enumerations
of UNIQUE values must be delared as anonymous integers which makes code
a lot less clear, and of course error prone.

Neil.
E-mail: nhr@uk.ac.cam.eng

rick@tetrauk.UUCP (Rick Jones) (12/12/90)

In article <18527@rasp.eng.cam.ac.uk> nhr@eng.cam.ac.uk (Neil Russell) writes:
>How about using a builtin type ADDRESS (a al Modula-2).  In modula-2
>the type ADDRESS is compatible with any pointer type (analogously
>class type in Eiffel), and in addition to assignment, arithmetic may be
>performed on values of type ADDRESS permitting the construction of
>memory managers.  This latter feature may not be suitable/relevant
>in the Eiffel context, where memory management (garbage collection) is
>hidden from the Eiffel programmer.  Portability considerations aside,
>the attraction of having a specific type (as opposed to integer or
>`bits N') is clarity.

This is essentially what I am proposing, although allowing any arbitrary object
to be attached to an ADDRESS type within Eiffel is dangerous and probably
unnecessary.  As Neil says, memory management is not something to be written in
Eiffel as it is an integral part of the run-time environment, and it is
difficult to imagine any other useful application of arbitrary manipulation of
object addresses.  Of course if you _really_ want to do it, you can have a
trivial C function which returns the address of an Eiffel object argument as an
external ADDRESS (or EXTERN or whatever) type.

My current project involves some extensive interfacing to C subsystems (AT&T's
Tuxedo, which comprises a network database, a TP client/server monitor, and a
message buffer system for starters), which has raised some distinctly
non-trivial problems.  We have solved all these within the current language,
and without resorting to anything nasty.  My only concern is the long-term
portability of Eiffel code which carries external addresses around in variables
which are explicitly integers (and hence C "int"s).

This prompts me to mention something else with external interfaces which is a
little annoying, in that even trivial access to C variables requires a C
_function_ to be written.  A common example is the need to import to Eiffel the
current value of a C global error code (e.g. errno) for error analysis.  This
requires a C function which is simply { return errno; }, and could be achieved
with inline code.  A nice addition would be the ability to specify an external
routine as "inline";  in this instance the inline code would simply be the word
"errno".  How about this:

	external
		c_error: INTEGER inline "errno" language "C" ;

There is in fact a whole load of stuff this simple in the Eiffel run-time
libraries.  All this could be drastically simplified by the introduction of an
inline facility.

A little more thought is required to cover all the possible legitimate uses of
inline code, but one important aspect is the ability to synchronise Eiffel and
C manifest constants in an elegant manner.  It needn't be too complex, anything
extensive should be a function anyway.  This of course assumes that the
compiler target language is C, but using external C functions almost assumes
the same.

>A not totally unrelated defficiency of Eiffel is the inability to
>define formal enumeration types -- entities representing enumerations
>of UNIQUE values must be delared as anonymous integers which makes code
>a lot less clear, and of course error prone.

Eiffel's UNIQUE mechanism is not a substitute for enumerated types, and is not
meant as such.  I have a few grumbles about UNIQUE, in particular, such values
should start at 1 not 0, and the language should specify this - at the moment
it just says that it's implementation dependent.  But UNIQUE declarations are
NOT enumerations.  A true enumeration type will refuse to hold any value other
than those with which it is declared, and Eiffel doesn't support one;  UNIQUE
is just a handy way of declaring a set of unique arbitrary integer constants.
If you want constants with known values you have to declare each one
separately.

A much bigger problem with constants is that you can't declare constants to be
constant expressions, so you can't declare new constants which depend on the
value of existing (maybe inherited) ones.  You also can't use constant
expressions in INSPECT statements, e.g.

	when Base then
		...
	when Base + 1 then	-- not allowed!
		...

There are situations where this is not a trivial problem.

Enough for now!
-- 
Rick Jones
Tetra Ltd.  Maidenhead, 	Was it something important?  Maybe not
Berks, UK			What was it you wanted?  Tell me again I forgot
rick@tetrauk.uucp					-- Bob Dylan

richieb@bony1.uucp (Richard Bielak) (12/14/90)

In article <18527@rasp.eng.cam.ac.uk> nhr@eng.cam.ac.uk (Neil Russell) writes:
>How about using a builtin type ADDRESS (a al Modula-2).  In modula-2
>the type ADDRESS is compatible with any pointer type (analogously
>class type in Eiffel), and in addition to assignment, arithmetic may be
>performed on values of type ADDRESS permitting the construction of
>memory managers.

To make this more like Modula-2, perhaps there should be a class
SYSTEM, that contains things like ADDRESS, and other hardware
dependent types (BYTE, WORD, LONGWORD etc) and function (eg.
get_address_of_something)

>A not totally unrelated defficiency of Eiffel is the inability to
>define formal enumeration types.

Although I'm not sure exactly why, but enumeration type present some
difficult problems to the compiler when types are extended through
inheritance. My evidence? Look at OBERON, latest language from N.
Wirth, it does not have enumerated types.


..richie



-- 
+----------------------------------------------------------------------------+
|| Richie Bielak  (212)-815-3072      |  If a thousand people say a foolish  |
|| USENET:        richieb@bony.com    |  thing, it's still a foolish thing.  |
+----------------------------------------------------------------------------+