Channels ▼



Source Code Accompanies This Article. Download It Now.


Ernie Tello is a consultant, lecturer and writer in the field of artificial intelligence. He can be reached at 1518 W Cliff Dr., Santa Cruz, CA 95060.

C_talk from CNS (Eden Prairie, MN) is an object-oriented hybrid C and Smalltalk programming languages. It couples the essential features of an object-oriented language such as inheritance, encapsulation, message passing, and run-time binding to the speed and efficiency of the C language.

In Prolog/V: "Prolog in the Smalltalk Environment" (see November 1988 issue), Gregory Lazerev took a detailed look at the synergy that developed from fusing the strengths of Prolog/V and Smalltalk/V into a potent development environment. This article explores how coupling the procedural language C to a Smalltalk-like object-oriented software environment can yield equally impressive dividends by allowing the incremental and interactive development of an object-oriented system written in familiar, portable C.

The C_talk system consists of three main programs: a Smalltalk-like browser, a preprocessor compiler, and a Make utility. The C compilers currently supported are: Microsoft, Lattice, Turbo, and C86. It's noteworthy that the same system supports all of these compilers. So no additional cost is incurred if you choose to switch compilers in midstream.

The feat that deserves the most attention is CNS's ingenious way of incorporating the Smalltalk-like browser into the C programming environment. The browser forms the real center of this programming tool. It can be used interactively just like the Smalltalk browser (in spite of the fact that C is a compiled rather than an interpreted language). To get an idea of the advantages presented by programming with a tool like C_talk, let's take a look at this innovative browser.

The C_talk Browser

It's surprising how similar the C_talk browser is to the Smalltalk facility that it was modeled after. Like its parent, the C_talk browser acts as a combination editor and application manager that allows object-oriented systems to be developed incrementally and interactively. That's no mean achievement for a C-based object-oriented tool.

The browser exists as a stand-alone program that's called like any stand-alone application. As it will be seen, however, it's this program that provides an extremely powerful facility for integrating virtually the entire C_talk system.

Not only does the program allow you to familiarize yourself with the environment through interactive browsing, but it can also be used for doing many of the programming chores interactively, including creating a Make file for batch processing the compilation and linking operations.

The C_talk browser is divided into a number of panes that operate like tiled windows, in that these apertures cannot be overlapped or re-sized. The upper left pane displays the class hierarchy. Just as with a Smalltalk browser, when a class is selected, its methods are shown in the upper right window pane. Then a method can be selected and its code is made available for editing in the bottom text pane.

Alternatively, any text file can be loaded into the browser and displayed in the lower text pane to be edited. Thus, the browser fills the dual purpose of a small, simple editor and a tool specially equipped for handling C_talk objects.

To operate the browser, various popup menus are available in different pane areas. These pop-ups can be activated either by mouse or key commands. Included in the browser facilities is a shell that allows you to issue commands to the operating system from within the browser or to temporarily exit to the operating system for doing various chores, and return to the browser just as you left it. This kind of shell has become so widespread that it is now really conspicuous when it is absent.

There is an important difference between the C_talk browser and a Smalltalk browser. The former is a stand-alone application in a compiled environment and the latter is part of an interactive system in which everything is omnipresent. When the C_talk browser is first loaded, (because it does not have the classes as part of itself) it looks for all the class definitions that exist in the current directory on disk and compiles them into its database so that it can provide interactive access to them.

Once everything has been loaded into the browser, however, many functions needed for writing applications can be done interactively, so that the browser actually generates the code. Such functions include specifying a new application, loading existing classes, defining new classes and their methods, and saving all work. There is also a zoom function that expands to the size pane of a full screen.

Everything was not yet "ideal" in the version of the browser I tested. For example, the ability to load text files into the editor is confined to rather small files. If the file you load into the browser editor is larger than the maximum size, only the amount that fits will be loaded, and no error message is given. This can be dangerous for the unwary, because if you were to make a small change and save such a file this could result in a substantial loss of data. For this reason, I would say that the browser is useful primarily for the "build" facilities that allow you to create various small files that will form modules in a complete system. For editing relatively large files I recommend that another editor be used.

C_talk Syntax

The syntax of C_talk is slightly different from other object-oriented C dialects, but if you already know C, once a few conventions are mastered it becomes relatively straightforward to read and write. The main convention concerning C_talk messages is that they are always flanked by two "at" (@) symbols on either side. So, for example, if we want to create a new instance of a class such as Rectangle, then the message would look like this:

     @Rectangle new_&[email protected];

Here the ampersand character is used for pointer notation exactly as in C.

The id statement is a C_talk class id declaration. In C_talk programs you must make external declarations for each class id that is referenced.

One of the most powerful features of C_talk is the ability to map one message to another. This means that the selector, or name of a message, can be passed as an argument to another message. The syntax for doing this is a variable assignment statement with the name of the message selector enclosed by backquote characters.

To actually send a message that references another message that has been stored as a variable, special messages are provided as methods of the Object class that are inherited by all other objects. These methods are perform_, perform_with_, and perform_with_with_.

So, for example, if we have defined the variable gval as follows:

     id gval;      gval = 'getValue';

and an object,

     id obj;      int gval;

Then the getValue message could be mapped by the expression:

     @#obj perform_gval with &[email protected];

Here it is assumed that val is a slot in obj, and that the getValue message takes this as an argument.

As with most object-oriented languages, the pseudo variables self and super are used to reference objects within a message. The self pseudo variable references the object to which the message is sent. The super pseudo variable references the superclass of a class. To access the instance variable of the object to which a message is sent, the following notation is used:

     self-> width

assuming that width is the name of an instance variable for the object in question.

Another C_talk syntax convention involves the use of the underscore character ( _). Whenever an underscore follows a message selector name, this indicates that an argument is to follow. From a practical point of view, one of the more important things about an object-oriented C system is the size of its built-in foundation classes, so we'll look at this next.

C_talk Foundation Classes

The Container class is an abstract or formal class that is used for creating subclasses that provide dynamic data storage elements. (See Table 1, page 77.) This means that a subclass of Container can allow instances to be created that have either fixed- or variable-sized data elements, as well as sequential or non-sequential access methods. So, for example, if the expand message is sent to an object, the object is doubled in size.

For more precise size expansion, the expandBy_ method is used, which takes an argument that specifies the number of additional data elements the expanded object will contain. The putRecSize_ method similarly sets the size in bytes for each data element that the object contains. To access an indexed object, you use the at_ get_nRecs_ method, which returns as many records as you specify, starting at the specified index number.

Nearly all of these foundation classes are various subclasses of the Container class for implementing various different types of data structures. Usually a dynamic data structure is defined much farther down the class hierarchy in an object-oriented system. This is a fairly innovative way of approaching the matter that has a lot to be said-for it.

The Buffer class is intended to provide a simple means of storing and maintaining large blocks of data in either byte or word formats. An immediate extension to this class that suggests itself is to add an instance variable that indicates whether a given Buffer object is a byte or word buffer. General read and write routines could then be written that first send a message to a buffer to see if it is in byte or word format. In this way, a program need not be specific to one type of buffer or the other.

The Stream class is implemented as A subclass of Buffer and includes one instance variable position as a way of indexing the current stream position. The Collection classes provide for objects in which other objects are grouped. The subclasses of Collection itself vary according to whether access to elements is ordered or random, and whether the size is bounded or unfunded. So, for example, the OrdCollect class allows elements to be inverted and retrieved in sequential order, and for the size of the collection itself to be expanded automatically as new elements are added.

Text Window Classes

Some additional classes have been developed by CNS that provide support for the creation of text windows in the C_talk environment. (See Table 2, this page.)

Let's look briefly at what some of these additional classes do. The Browser class provides some of the basic methods for creating a browser similar to the one included in the C_talk system. Over 20 methods are supplied with this class. Even a main program is included for creating a test browser program. This code can produce a "test browser" that lacks various things that the real tool has, but shows many of the essentials of how the tool is created. For those who want to develop their own custom browser that they can continue to extend at will, this code will represent a flying head start in that direction.

Table 1: The foundation classes are listed in hierarchal format.


The Browser class is a direct sub class of Object that makes use of the TxBuffer, TxEditor, Response, and File classes. The TxWindow class and its subclass TxEditor coordinate handling text in windows by sending messages to objects in nine different classes. Together they handle processing keystrokes and managing characters in buffers.

Table 2: The additional classes are arranged hierarchically.


Window is the abstract class for forming most of the classes that are used for defining the various features of windows, such as those used by TxWindow. The WinManager class is the one that ties it all together. This class sends messages to most of the other classes so as to coordinate their behavior. Currently, it has a total of about 17 methods. A quick way to get an overview of what it does is to take a peek at its initialize method, which is reproduced here in Example 1, page 76.

Example 1: Initializing the reciever

/* Initialize the receiver: set up MetaWindow, win_list and create root */
/* window.     */
{    id        newWin;
     int       w, h;
     extern    id Menu;

     @Screen Mgr create_ &[email protected];
     self->color = @Screen [email protected];
     w = @Screen [email protected];    h = @Screen [email protected];
     @Mouse create_ &[email protected];      /* init mouse service routine */
     @Mouse setColor_ self->[email protected]
     @OrdCollect new_ &self->winList size_ [email protected];
     @Window new_ &newWin par_ NIL x_ 0 y_ 0 wdth_ w hght_ [email protected];
     self->rootWin = newWin;
     @self->rootWin getAbsRegion_ &[email protected]; /* init movement box */
     /*@self->winList add_ self->[email protected]; */
     self->activeWin = self->rootWin;
     Dispatcher = @Notifier [email protected]; /* an instance of the event manager */

The initialization routine first sends a message to the Screen Manager and tells it the type of screen to create. Then the Mouse object is told to create the specified type of cursor. Next an Ordered Collection object is created to serve as a window list. Then the Window object itself is created with the designated proportions and attributes, and finally an Event Manager is created. This is an excellent example of how C_talk makes use of one of the main paradigms in object-oriented system design, that of employing one object as the manager of other objects. The only shortcoming of this approach is that it tends to bog down when the number of objects involved gets large.


Completing a C_talk application is generally a five-step process. The first step is to write the necessary source code files in the C and C_talk syntax, which is written in disk files with the .PRE file extension. The second step is to write a main routine in C that calls all the necessary modules. Once this is done, the third step can be taken, which is to run the preprocessor and compile all the C_talk files into the corresponding C files. The fourth step is then to compile all the C files with a C compiler. Finally, the compiled .OBJ files are linked together to form the executable file for the application.

For those who wish, as mentioned earlier, there is a convenient way of collapsing some of these steps using the make option in the C_talk Browser. To do so, you would select the Make Spec pop-up menu. The result of using this interactive procedure is the creation of a .MAK file that can be used by a special auxiliary program that will automatically carry out the three steps of preprocessing, compilation, and linking as a batch process. And since the browser supports calling DOS commands, and exiting to DOS, it is not necessary to exit the browser to make the finished executable and even test it afterward.


C_talk succeeds very well in doing what it sets out to do, namely provide a language that is a true hybrid between C and Smalltalk. The browser puts it in a class all by itself among other similar attempts. One thing that should be pointed out is that a major difference between Smalltalk itself and all of the C hybrids that have appeared so far is the great difference in the number of foundation classes present. As it is sold, Smalltalk is not just a bare-bone language, but amounts, in effect, to a language plus a large generic function library that is standard in this case by definition.

For this reason, the Window classes we have described are an Important addition for the C_talk system. The importance of these library classes can be appreciated when you recall that objects in an object-oriented system are working parts for programs rather than just stand-alone functions. In a sense, then, a system with a large class library is one with a substantial part of the programming already done. The downside is that the programmer has to learn these classes and how to use them. Although one of the advantages of the object-oriented approach is that this is all done generically, the learning curve still exists for class libraries.

One minor potential drawback with this type of system is that it is set up to work mainly with C_talk source code in the browser. If a developer wants to sell class libraries in the object file format, it will not be possible to use them with the browser in the current design. Perhaps a way can be devised for loading key class information into the browser without divulging all the source code involved. This would allow the browser to be used even with object code class libraries. The main thing to emphasize is that C_talk has all of the essential things of a true object-oriented language, and the browser has done well enough to give the interactive feel of a Smalltalk environment while offering all the advantages of any C-based system.

Product Information

C_talk, Version 1.4; CNS Inc., 7090 Shady Oak Rd., Eden Prairie, MN 55344; 612-944-0170. PCs and compatibles. Requires: DOS 2.1 or later; graphics card; and one of the following: Microsoft C, Lattice C, Turbo C, or C86. A hard disk and a mouse are recommended. Price: $149.95.

_C-TALK_ by Ernie Tello


Ctalk Foundation Classes = Table 1 The foundation classes are listed in hierarchical format.

Object Assoc Container Buffer Stream ByteArray Collection OrdCollect Stack Set Dictionary IntArray String


Text Window Classes -- Table 2 The additional classes arranged hierarchically.

Browser File Menu Mouse Notifier ScreenMgr TxPoint Window ButtonWin ItemWin Scrollbar StdWindow ListWindow HorListWin PopUp Response TxtWindow TxEditor WinManager



<a name="0231_000f">

/* Initialize the reciever: set up MetaWindow, win_list and create root  */
/* window.   */
{ id      newWin;
  int     w, h;
  extern  id  Menu;

  @ScreenMgr create_ &[email protected];
  self->color = @Screen [email protected];
  w = @Screen [email protected];   h = @Screen [email protected];
  @Mouse create_ &[email protected];            /* init mouse service routine */
  @Mcursor setColor_ self->[email protected];
  @OrdCollect new_ &self->winList  size_ [email protected];
  @Window new_ &newWin par_  NIL  x_ 0 y_  0 wdth_ w hght_ [email protected];
  self->rootWin = newWin;
  @self->rootWin getAbsRegion_ &[email protected]; /* init movement box */
  /*@self->winList add_ self->[email protected];*/
  self->activeWin = self->rootWin;
  Dispatcher = @Notifier [email protected];    /* an instance of the event manager */


Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.