Debugging C
Volume Number: 5
Issue Number: 2
Column Tag: Programmer's Forum
Lightspeed C Debugging
By Gary Odom, Plano, TX
Gary Odom is a software developer for Altsys Corporation (Freehand,
Fontographer, Fontastic Plus), and a long time friend of MacTutor. Gary kills his
spare time working on an AI project for the Japanese market.
Overview
Think’s LightspeedC is a C development system produced by Symantec
Corporation. THINK C’s claims to fame have been its fully integrated environment,
blazing speed, and ease of use. A new version, 3.0, came out the beginning of August,
sporting a source-level debugger. This article is a review of THINK C 3.0, with
special emphasis on the new debugger. First, some overview for those not familiar
with the product.
All development in THINK C occurs in one application. The editor, compiler and
linker are all integrated under one menu bar. THINK C uses the concept of a project
for building an application or other code resource. All source files and libraries used
to build an application are listed in a project window (Figure 1, bullseye π). You can
double-click on a file name in the project window to open that file. All object code is
kept in the project file.
THINK C allows you to easily build most any kind of code, from applications to
desk accessories (and other drivers) and FKeys (and other code resources).
Segmentation of a large project is simple: you simply set a file or library into a
segment. No separate link command file is needed.
You can write inline assembly with THINK C. Particularly convenient is the
ability to use C identifiers directly, including structure members.
You can use, and even require, function prototypes in THINK C 3.0. Function
prototypes, a new ANSI C feature, provide function type checking previously lacking in
C (unlike Pascal, where such type checking is an integral aspect). Checking pointer
types is also optional.
New with 3.0 is the ability to precompile headers, to speed inclusion of header
(.h) files. There is a default file, MacHeaders, that has the common Macintosh
includes. You can edit that and recompile it to include a different set of Mac includes,
or use any precompiled header file you construct (in lieu of MacHeaders). There is a
limitation that only one precompiled header can be included in source file, though you
can get around that (in a way) by including a precompiled header file in a
self-constructed header file to be precompiled (nested precompiled headers).
You can interactively compile and run a project to test execution. Because THINK
C uses an incremental linker, link time is negligible. (When you finally link/create an
application, though, you must wait for the object code and resources to be copied into
the application file.)
I’ve read several articles that recommend THINK C for individual projects, but
MPW for group projects. I don’t understand why. It is very easy to merge a group
project in THINK C, a reason often cited for preferring MPW. New code can be added to
a project as libraries, completely separate projects (which behave like libraries), or
individual files.
I’ve seen tables on the code generation quality of THINK C versus other
environments. The intention of this article is not to provide yet another set of
benchmarks. Suffice to say that THINK C produces executable applications with code
that is both compact and swift, relatively speaking (MPW C being first cousin).
Symantec is always working on ways to improve compilation. For me, it’s comforting
to know that a product is receiving constant upgrade attention by a dedicated team.
Evaluation
There are a lot of things to like about THINK C, with convenience and speed being
at the top of the list. The user interface and seamless integration are what make THINK
C so easy to use. While THINK C has a plethora of features, there are a few it doesn’t
have that I’d like.
QUED/M by Paragon Concepts is a macro editor for the Mac that is a yardstick of
excellence for text editors to be measured against. By comparison, the editor included
in THINK C is convenient and fast, but lacks some desirable features. What is
particularly good about the THINK C editor (besides being fully integrated into the
environment) are the search and replace functions (including Grep), and convenient
window management (command keys 0-9 bring the project window and up to nine text
file windows to the front). Another good feature is that you can Option double-click a
variable or function and go straight to the variable or function declaration (though you
can’t get back using a similar method).
Some features noticeably lacking in the THINK C editor are split screen windows,
a change case capability, and a gremlin zapper to rid the text of unneeded spaces and
option key characters that can cause the compiler to mysteriously barf. I use the
THINK C editor most of the time, as it is integrated into the environment. But for
industrial strength text sessions, I find myself in the MultiFinder stagecoach with
QUED/M riding shotgun.
There is an info window, which shows object code sizes for files, segments and
the project. I consider it useless. But it would be nice to know the number of lines of
code in the source file and project, which isn’t shown.
There is a default teletype (text console) window and default menus that
spontaneously arise when you use printf() or other standard I/O. This is useful for
testing code and not much else. I like the extensive console package provided by
Consulair Mac C, where any window can be set as the console (without obligatory
menus if appropriate), which means printf() can be used with any window, saving the
tedium of formatting text using DrawString() and pen movement routines from
Quickdraw.
MPW C is going to be extended to include C++, an object-oriented extension of C.
While a degree of object-oriented programming can be accomplished via sheer
technique (without language extensions), C++ provides the full capability of object
orientation, and is the next evolutionary step in the C language. Symantec is
considering how best to implement C++ while not making it an interference in terms
of user convenience and quality code generation. Don’t look for THINK C++ Real Soon
Now, but, according to Symantec, it’s probably in the pipeline for the next major
release.
Symantec is receptive to new features for THINK C. They recently sent a survey
to get some feedback. Contact Symantec with your suggestions. Now is a particularly
good time, while they are catching their breath from the latest release.
Debugging
In previous versions of THINK C, running a project interactively meant having to
use TMON or MacsBug to sift through the wreckage of a crash. No more. (Though you
can still use TMON or Macsbug via the “Monitor” menu item in the Think C Debugger.)
THINK C 3.0 has a new source-level debugger. There is a caveat, however. You must
have at least 2 Mb of memory to use the debugger, which runs under MultiFinder.
(THINK C takes a default 700 Kb, the Debugger 200Kb, and 384Kb for your
application.)
To use the debugger, you must compile source with the “Use Debugger” menu
option enabled. A bug shows in the project window to indicate debugging is enabled
(Figure 1, bullseye π). Diamonds by the files indicate which source can be stepped
into to trace execution. Libraries (such as MacTraps) cannot wear a diamond, as the
source is not available.
When you run with the debugger enabled, a solid arrow indicates the current line
of execution (Figure 1, bullseye.c). The data window to the right is for examining
variables.
Clicking on a hollow diamond on the left of the source window sets a breakpoint,
making the diamond solid. Likewise, you click a solid diamond to remove a breakpoint.
You can easily set temporary and conditional breakpoints.
The buttons at the top of the source window (bullseye.c in Figure 1) control
execution. “Go” runs the program until a breakpoint is encountered. “Step” executes
the current statement, stopping at the next statement. “Trace” is similar to “Step”,
but goes into a called routine to the next executable line (unlike step, which executes
the called function without going into it). “In” steps into a function. “Out” finishes
executing the routine it’s in and pops out. “Stop” halts execution.
You can look at the current value of variables in the data window. The huge check
is an enter button (same as the Enter or Return key). The big X is a deselect button
(same as clicking elsewhere to deselect). Identical variable names can occur in a
source file, so you often need to click on the line that has the variable to provide the
correct context for the data window. If you forget the context of a variable in the data
window, you can find out using the “Show Context” menu item.
If you want to look at the members of a structure or the contents of a structure
for which you’ve got the pointer or handle, you double-click on the data (right side of
the Data window) to deference to the next level, until you bring up a new data window
that has the structure members (Figure 1, *bullseyeWindow).
You can edit the source within the debugger, a convenient feature when you find
some nasty critter in your code. (Of course the changes don’t take effect until you
recompile.) The debugger remembers the original, unedited source as long as memory
constraints allow.
The debugger is friendly, full-functioned and fast. It integrates nicely into the
environment. Though I have crashed in the debugger upon occasion, I consider it
relatively stable.
Documentation
Two 7 1/2 x 9 x 3/8 inch manuals come with THINK C 3.0: a 260 page User’s
Manual, and a 212 page Standard Libraries Reference. The manuals are high-quality
soft cover perfect bound (like a regular book). One nice feature of the manual is an
outer shell cover to the binding (called otabinding), so you can lie the book flat and
can’t break the spine of the manual. It is indicative of the entire THINK C package in
that great attention has been paid to getting the details right.
Of course, what’s inside the manuals is what really counts. The documentation
has been completely rewritten, and is a vast improvement over version 2.15. The
User’s Manual begins with a thorough tutorial, followed by a reference section. The
writing is clear, concise and complete. The Standard Libraries Reference is a listing
and explanation of the standard C and Unix library functions included with THINK C.
Conclusions
THINK C is so easy to use that it makes a fine backyard for a novice C code puppy,
yet is full featured and slick enough for the professional code dog at the corporate
kennel. Many Mac software houses, including Altsys, use it for their product
development. The source-level debugger empowers THINK C 3.0, making its use a
more pleasurable and highly productive experience.