(gtk.info.gz) Type introduction
Introduction to the Type System
Gtk defines its own system of types, much like a computer language
defines what types it supports. Of course, the Gtk type system is build
on top of the types that C provides, so it includes members like `int',
`long' and `float'. But, compared to C, it allows only few carefully
selected types and specifies a lot of restrictions on the way you can
use values of these types. For example, there is no general facility
for specifying _pointer to X_. Instead, we take a more higher level
approach and define such things as `string', which is just like a
`char*' but with additional rules about how to manage the memory that
it points to.
The type system has two purposes: to define a formal system with
which to describe the various exported features of Gtk; and to
implement this system at run-time so that we get sound and flexible
"dynamic" types for the dynamic languages that want to interface with
Let me restate this with different words, because I think it is
important to understand this idea. We will see in a moment that the
type system is indeed well defined and all this detail is implemented
with functions and data structures in Gtk. For example, every type (and
there can be any number of them) can be represented with a unique
integer and Gtk has support for the necessary bookkeeping for this.
Every type also has a name and there are functions for converting
between the name of a type and its unique number. Maybe more useful,
there is a big discriminated union that can be used to pass around a
value of any representable type, together with its precise type.
This is the run-time or dynamic side of the type system. Mostly,
you do not need to use it when you don't want to. The compile-time or
static side of the type system can is used to statically define the
programming interface of Gtk. For example, suppose there is function
`gtk_foo' in the Gtk API that has a prototype
char *gtk_foo (char *);
This looks like it does something with strings. But what does it do
with the memory of the string that has been passed in, and what are we
supposed or allowed to do with the memory that the returned pointer
points to? The more restricted type `string' from the Gtk type system
can be used to be more precise. In fact, the definition of `string'
below includes the rule that when a `string' is passed to a function,
that function is not allowed to retain a pointer into the string beyond
the life time of that function call. So we are safe to deallocate it
or override it when the function has returned. Likewise, the
definition specifies that the memory of a `string' that is returned
from a function becomes the sole property of the calling function. The
calling function is responsible for deallocating it eventually and it
can be sure that nobody else scribbles in it. When `gtk_foo' really
obeys these rules, we can say that it takes one argument, which is a
`string', and it returns a `string'.
Now we can understand why it makes sense to have a more restrictive
type system than that of C. With it, it is possible to be more precise
and we actually have a framework where we can be sure that as long as we
stay inside this framework we are not gratuitously causing trouble for
languages that are more disciplined than C. Of course, you are not
restricted to making all your interfaces expressible within the
framework. There are valid reasons for breaking it, for performance or
simply for convenience. But please try to provide all the functionality
of your module in such a way that it can be described with this type
system and treat the non-conforming functions as additional goodies that
are nice to have but not essential. The reward is an instant
accessibility of your code from a huge number of scripting and extension
languages such as Perl, Python, and Guile.
These formal specifications of the Gtk interface are contained in
special declarations in the header files of Gtk. They are ignored by
the C compiler, but can be used by other language processors. For extra
convenience, these declarations are also available in a more condensed
form that is easier to parse. Tools for generating bindings of Gtk to
other languages can read these declarations and--because all the
important details are defined--automatically generate the bulk of the
needed glue code. It is also possible to feed these declarations into a
running application (an interface builder, say) and thus make it aware
of new widgets and functions without recompiling anything.
The run-time side of the type system is also somewhat introspective.
This means that you can query Gtk about all the members of an
enumeration for example. Gtk provides tools that help you provide this
introspection for your definitions also.
Types are not enough to completely specify an interface, so GTK also
has "modes". A mode specifies what happens to a value when it crosses a
module boundary; it can be `in', `out', or `inout'. Most fundamental
types (and their derived types) support only mode `in'. The modes
`out' and `inout' can only be used with the composite types: lists and
vectors. When argument of these types are marked as `out' or `inout'
it means that the called module is allowed to change the contents of
the composite value and that these changes need to be propagated back
to the originator of the value. Mode `out' means that the argument has
no meaningful value at the beginning and should not be read. Mode `in'
specifies that the called module is not allowed to change the value in
The type system allows for an unbounded number of types. Every
widget is a type for example and you can add new widget types at any
time without confusing the run-time implementation of the type system.
Nevertheless, all types are derived from a certain "fundamental" type,
and there are only a small and finite number of fundamental types. We
only specify rules for the fundamental types and all other types
inherit these rules from their fundamental type. For example, `int' is
a fundamental type, as is `GtkObject'. All widgets derive from
`GtkObject' and so the rules for `GtkObject' apply to all widgets as
This derivation defines a type hierarchy, but this hierarchy is not
completely general. You can't derive from `int' for example, and you
can only have one level of derivation from `enum'. The fundamental
type `GtkObject', however, is the basis for the large and deep
hierarchy of widget types.
The individual fundamental types are defined and explained in the
following sections. Here is a complete list of them:
The not-a-value type, similar to `void'.
A character. Internationalization issues are still undecided.
True or false.
`byte, ubyte, int, uint, long, ulong, float, double'
The usual assortment of scalar types.
A string. Internationalization issues are still undecided.
Enumerations with a fixed set of literals. Either used to express
a single choice from this set or to individually turn on and off
A pointer to an opaque structure that can be copied and destroyed.
A pointer to a function with enough extra information so that it
can also be used for functions written in languages completely
different from C.
A pointer to a GtkObject or derived type. The fun starts here.
`args, slist, dlist, cvec, tvec'
An assortment of composite types like linked lists and counted or
`pointer, signal, c_callback'
automatically generated byinfo2html