Copyright (C) 2000-2012 |
GNU Info (gtk.info)Type introductionIntroduction 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 Gtk. 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 any way. 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 well. 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: `none' The not-a-value type, similar to `void'. `char' A character. Internationalization issues are still undecided. `bool' True or false. `byte, ubyte, int, uint, long, ulong, float, double' The usual assortment of scalar types. `string' A string. Internationalization issues are still undecided. `enum, flags' Enumerations with a fixed set of literals. Either used to express a single choice from this set or to individually turn on and off several flags. `boxed' A pointer to an opaque structure that can be copied and destroyed. `callback' 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. `GtkObject' 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 zero-terminated arrays. `pointer, signal, c_callback' Obsolete types. automatically generated by info2www version 1.2.2.9 |