From: gb@cs.purdue.edu (Gerald Baumgartner)
Newsgroups: gnu.g++.announce,comp.lang.c++,comp.object
Subject: GCC 2.3.3 implementation of signatures for C++
Date: 27 Dec 92 10:21:00 GMT
Followup-To: gnu.g++.announce,comp.lang.c++,comp.object
Organization: Department of Computer Sciences, Purdue University
To: gnu-g++-announce@cis.ohio-state.edu

A beta test version of our implementation of signatures for C++ has
been released and is available by anonymous FTP from:

	host:		ftp.cs.purdue.edu	(128.10.2.1)

	login:		anonymous

	password:	your e-mail address

	directory:	pub/gb

	files:		COPYING			Copyright notice.

			README			This file.

			gcc-2.3.3.sig.diff.Z	Context diffs for GCC 2.3.3,
						also work for GCC 2.3.2.

			pldi.dvi.Z		Paper submitted to PLDI '93
						(compressed DVI file).

			pldi.ps.Z		Paper submitted to PLDI '93
						(compressed Postscript file).

			test.tar.Z		Test files and script to run
						the tests.

To make GCC 2.3.3 (or GCC 2.3.2) understand signatures, just copy the
context diff file into the GCC source directory, type

	zcat gcc-2.3.3.sig.diff.Z | patch

and recompile `gcc' and `cc1plus.'

For compiling C++ code containing signatures, you need to use the
command line option

	-fhandle-signatures

We tested our extension on Sun 4 only, but since there are no changes
to the compiler backend, it should work on other architectures as
well.  To test whether it works on your architecture, unpack the file
`test.tar.Z' and run the shell script

	Test

It compiles the test programs and runs them.  If everything works
correctly, all the test programs (all 37 of them) should print

	Hello World.


What are Signatures anyway?
---------------------------

Roughly, signatures are type abstractions or interfaces of classes.
They are related to ML's signatures, categories in Scratchpad II,
definition modules in Modula-2, interface modules in Modula-3, and
types in POOL-I.

The main language constructs added are signatures and signature pointers.
For example, the signature declaration

	signature S
	{
	  int foo (void);
	  int bar (int);
	};

defines a new abstract type `S' with member functions `int foo (void)'
and `int bar (int).'  Signature types cannot be instantiated since they
don't provide any implementation.  Only signature pointers and signature
references can be defined.  For example,

	C obj;
	S * p = &obj;

defines a signature pointer `p' and initializes it to point to an object
of type `C,' where class `C' is required to contain the public member
functions `int foo (void)' and `int bar (int).'  The member function call

	int i = p->foo ();

executes then `obj.foo ().'

Class `C' is called an implementation of the abstract type `S.'  In
this example, we could have made `S' an abstract class and `C' a
subclass of `S,' and we would have had the same effect.  The advantages
of signatures over abstract classes are

	- we can build a type hierarchy separate from the class inheritance
	  (implementation) hierarchy,
	- subtyping becomes decoupled from inheritance, and
	- signatures can be used with compiled classes, while we cannot
	  retrofit an abstract class on top of compiled class hierarchies.


Differences between Paper and Implementation
--------------------------------------------

The paper does not reflect accurately what has been implemented.  The
paper is in the form as we submitted it to the PLDI '93 Conference on
Programming Languages, Design, and Implementation (modulo some corrections
of typos).

There are three main differences between the paper and the implementation:

     1. For a class to conform to a signature, there must be class member
	functions with EXACTLY the same return type, number of arguments,
	and argument types as specified in the signature.

	It is not possible for the argument types of the class member
	function to be supertypes of the argument types as specified in
	the signature.  To implement this, signature table entries would
	need to point to little pieces of code which perform the necessary
	conversions and then call the class member function.

     2. Signature pointers and signature references take up three words
	of memory as opposed to two words as mentioned in the paper.  We
	needed to add a virtual function table pointer `vptr' in addition
	to the fields `optr' and `sptr' to be able to call virtual class
	member functions correctly.

	The need for a `vptr' field in a signature pointer arises because
	`vptr' fields in objects are not at a well-known location.  If
	every object of a virtual class would have its `vptr' at offset 0,
	say, we would not need a `vptr' field in the signature pointer.

     3. Signature table entries take up two words of memory instead of one
	word as described in the paper.  Since signature tables are allocated
	in static storage, the additional memory requirement shouldn't hurt,
	but it makes signature member function calls faster because no bit
	operations are needed to extract the flag that distinguishes between
	virtual and non-virtual class member functions.

	Also, to allow a signature pointer to point to an object of a class
	that is defined using multiple inheritance, we need to store more
	information in a signature table entry.  The additional field needed
	is the offset by which `this' is changed when calling the class
	member function.


Not yet Implemented Language Constructs
---------------------------------------

The following language constructs and features are not yet implemented.
This list is roughly in the order in which we intend to implement them.

      - No debug information is output for signature pointers and
	signature tables.
      - The destructor of objects cannot be called though signature pointers.
      - A signature pointer cannot point to an object of a class defined
	by multiple inheritance.
      - Signature default implementations are not implemented.
      - The signature conformance check does not work if the signature
	contains other signature declarations, class declarations, or
	opaque type declarations.  A `typedef' referring to a built-in
	type or a type defined outside the signature causes no problems.
      - Operator and conversion operator member functions of signatures
	cannot be called with operator call or conversion syntax.  They
	can be called with function call syntax, though, such as
	`p->operator+(17).'
      - Signature references are not implemented.
      - Signature inheritance is not implemented.
      - The construct `sigof' for extracting the signature information
	of a class is not implemented.
      - Exceptions cannot be specified with signature member functions.
      - Signature templates are not implemented.
      - Looking up a virtual class member function through a signature
	pointer/reference requires double indirection.  This can be optimized
	by memoizing, so that only the first lookup of a member function
	requires double indirection and further lookups require only one
	indirection.

Q: With so many features not yet implemented, is there anything implemented
   at all?

A: Yes, all the syntax analysis and error reporting is in place and the
   main language constructs `signature' and signature pointers are nearly
   fully implemented.  The parts that are implemented should cover most
   uses of signatures, and in most cases where something is not implemented
   the compiler reports that.


Feedback
--------

Please, send your questions, comments, suggestions, and complaints to

	gb@cs.purdue.edu

Cheers,

Gerald
Newsgroups: gnu.g++.lib.bug