
- Home
- Magazine
- Conference & Seminars
- News
- Archives
- Forums
- Store
- Directory
- Editorial
- Advertising
- User/Login
- Contact



Jesse Feiler knows that Elvis lives-in Michigan-and that he's busy writing MacApp software. Perhaps any Pascal programmer can reach this level of mental acuity just by writing a small application in MacApp 3. See for yourself-follow Feiler, prior Pascal programmer, as he is baptized by total immersion into a new life of C++.
This article relates the travails of a Pascal programmer who learned C++-the why, the how, and the wherefore. In spite of all the words that have been written and shouted in the language wars, perhaps this will add something to the conversation and help those who follow a similar path to MacApp 3.
While I was learning C++, a colleague working on the same project was learning both MacApp and C++ (he knew Pascal). We both felt MacApp was much more important and difficult to learn. In terms of designing an application, knowing the MacApp classes and methods provides far more advantage than knowing C++ or Pascal.
Although I will return to these points below, it is important to note two things. First, I didn't need to learn C++ to program with MacApp 3. Second, I was able to read and understand MacApp 3 code from the beginning-but only with the assistance of MacsBug and my prior knowledge of MacApp. If you've ever cuddled up in bed with the MacApp source code on a cold winter night (yecch!), I'm sure you'll agree that you could probably understand DoMenuCommand even if it were written in an Urdu derivative of BASIC.
Obviously, the sort of undisciplined code I associated with C is discouraged in C++.
As a manager, I've also formed a few opinions about languages. I don't present these as facts, merely as personal prejudices. Here are some of them:
As you may realize from this list, in my own work, I stuck to Pascal. When I subscribed to ETO, the one piece of the puzzle I had to buy was C++, so I did. I never installed it, and didn't even look at the documentation. And when it was announced that MacApp 3 would be written in C++, I didn't feel that the world was coming to an end, since everyone stressed that we'd still be able to use Pascal for our applications.
Then the language war broke out. As noted in the sidebar accompanying this article, our language war was a bush-league event. Still, as my kilobyte charges on AppleLink kept increasing, I began to get more curious.
Then a new project came up, and I decided to implement it not only with MacApp 3 but to use C++ as well. I used C++ on this project in order to find out enough about C++ to take a side in the language wars. You don't have to use C++ in order to use MacApp 3. I only learned C++ to find out what the fuss was about.
While this technique (if you want to dignify it with that term) was an ad hoc, idiosyncratic approach, some of the things I did may be useful to others. The steps I took had the virtues of getting me up to speed in two weeks and getting an application that uses MacApp 3 and C++ into a basic shape in four weeks.
The advantage of this approach was that I had the structure of my still tiny application visible to me, and I had at least pseudo-C++ code generated by the PascalToCPlus tool.
The PascalToCPlus tool is a good start, but the new P2CPlus tool distributed with MacApp 3.0b1 (on ETO 5) is far superior. Also of help is the "cheat sheet" located in the tools folder of MacApp 3.0b1. It contains samples of failure handling code, switch statements, and comparisons of Pascal and C++ common words and phrases.
If I couldn't find clues from MacApp itself, the next easiest way to get rid of errors was to simply comment out the offending lines. Since the application at this point did little except put up its menu bar, removing code didn't decrease its functionality very much.
I found two MacApp 3 documents to be critical: "Release Notes" and "Conversion Notes." They are included in the MacApp 3 documentation on ETO, and have been updated with new releases of MacApp.
As I started to compile, I started learning very fast. Here is the fruit of my labors-may they help others to make fruit salad, to go with Eric Berdahl's soup.
With a two-pass compiler, it's important to remember that errors are not necessarily emitted in the order they occur in the source file. Since compilers frequently generate errors on lines other than those where the actual errors occur (such as when quotes are mismatched), this can make debugging harder. Also, some syntax that is legal in Pascal is lethal in C++.
Herewith, a few of our more common errors. They are described along with the compile errors they generate and their most common cause-which is not necessarily related to what the compiler thinks is the problem!
These errors are the most common problems we've experienced that are not immediately caught and presented in an intuitive way by the C++ compiler. They're not to be interpreted as complaints about the C++ compiler, or about the Pascal compiler, or about the languages themselves. They are just the traps we hit most often. Some of them may hit any novice C++ programmer; others (like the absence of the word "case", below) are more likely to hit Pascal programmers because the two languages share similar syntax.
switch (selection)
{
case x:
…
break;
case y:
…
break;
default:
…
break;
};
If you revert to Pascal case syntax, you'll get compile errors and know to fix them. But two important things may confuse the compiler. If the word "case" is missing, then "x" and "y" above are interpreted as labels. An error is generated-usually at the beginning of the function, that says:
# warning: label cAddSequenceComponent not used
Since we rarely use labels and often use case and switch statements, we've found this message almost always means a missing "case" in a switch statement.
A more dangerous trap is that "break" is required to get out of the switch statement. Without it, the subsequent lines of code are executed. While this allows some neat programming, it's not something we're used to, and it doesn't generate a warning or error message.
All compilers are prone to conniption fits in their headers or interfaces. (Try leaving "USES" out of a Pascal interface file!) CFront is particularly unhappy with misspellings. In order to declare a constant, you can type:
const short i = 2;
Try typing:
cosnt short i = 2; //s-n reversed
…and you'll get:
line 35 # error: syntax error line 36 # error: syntax error line 36 # error: argument type expected for AddDependent() line 37 # error: syntax error line 37 # error: syntax error line 37 # error: syntax error line 37 # error: argument type expected for Insert()
Needless to say, line 35 is several lines beyond the const declaration. When the C++ compiler gives up the ghost and gives you the plain unvarnished "syntax error," we've gotten used to poring over code before the line in question, hoping to find a typo.
replacement = := equality == =
Thus, the phrase:
a=b
is a boolean expression in Pascal and a replacement operation in C++. The fun arrives when you code the following in C++:
if (a=b)
To a Pascal programmer, the code looks perfectly correct, and hours (trust me!) can be spent tracking down why the program executes strangely. As a result, Pascal programmers have to spend extra attention to if statements until they get them under their skin.
aSummaryView = aComponent->CreateSummaryView;
To a Pascal programmer, this looks pretty decent. Unfortunately, you will not call the CreateSummaryView(void) function and, in this case, you'll get the error:
line 75 # error: bad assignment type:
TView * = pascal TView *TComponent:: ()
aWindow->Open
instead of:
aWindow->Open();
will produce:
line 86 # warning: result of -> expression not used
This is a warning, not a compile error, so you'll be able to link, and run, and tear your hair out as a result of making the error and ignoring the warning. By now we know: this message means missing "()".
TView aView
instead of:
TView* aView
gives these errors:
line 61 # error: can't declare a handle/pascal object: aSummaryView
line 75 # error: bad argument list for TView::TView()
(no match against any TView::TView())
line 81 # error: non pointer -> Locate
Again, this is a fairly common mistake for Pascal programmers, because the "*" isn't something we usually worry about. So, translate "can't declare a handle/pascal object" to "missing *" and don't worry about what the message means. [1]
In C++, however, cut and paste can't be used, since the semicolon at the end of the function definition (i.e., interface) is required, and a semicolon at the end of the function declaration (i.e., implementation) is forbidden.
As with most header or interface errors in all compilers, errors in this area can cause nasty results. Omitting the semicolon after the definition in the header file will generate a small novel of the following sort:
line 70 # error: syntax error: unexpected pascal
(did you forget a `;'?)
line 70 # error: function declared as both pascal and non-pascal
line 41 # error: function declared as both pascal and non-pascal
In our experience, the first (and most welcome) message, suggesting the missing semicolon, is not reliably produced. The giveaway to the missing semicolon is more often the error "function declared as both pascal and non-pascal." Note the non-sequential error messages, with line 41's message following the messages for line 70. This is typical of two-pass compilers. Also of interest is the fact that this group of error messages was generated by one missing semicolon-and that was on line 70. Line 41 is the beginning of the class definition.
line 229 # error: qualified name THEComponent:: GetControlParms() in function declaration line 230 # error: syntax error line 237 # error: syntax error line 237 # error: function declared as both pascal and non-pascal line 237 # error: two different return value types for TickCount(): unsigned long and int line 239 # error: syntax error line 239 # error: syntax error line 239 # error: syntax error line 240 # error: syntax error line 241 # error: syntax error line 241 # error: anachronism `.' used for qualification; please use `::' line 241 # error: bad qualifier fi for Try() line 310 # error: syntax error line 311 # error: syntax error
As in all cases where a compiler has gone off the deep end, errors multiply, generating more and more esoteric (and incorrect) messages. In our experience, the words "qualified name <> in function declaration" are the tip-off to the extra semicolon.
warning: TCommComponent::HandleMouseUp() hides virtual TView::HandleMouseUp()
Unless you really meant to overload the function, check the definition of your function and its ancestor's for differences in spelling, type, and number of arguments. Of course, if you meant to overload the function, ignore the warning.
Warnings are easy to ignore, since they don't stop the compilation process. But compilers rarely emit warnings that should go unheeded. As noted above, some of the errors Pascal programmers are likely to make in C++ will only generate warnings. So it's a good idea, one way or another, to eliminate warnings from your compilation.
SourceBug provides line-by-line tracing of program execution. This is crucial for debugging- particularly in cases where control of execution goes in places where it's not expected to.
MAMake deserves to be mentioned because the dependencies in your MAMake file have to be absolutely correct (as indeed they should be with Pascal). Unfortunately, since C++ assumes that you may want to overload functions and change their parameters, some of the typos that the Pascal compiler would catch are treated by C++ as conscious, deliberate choices. So, in a back-handed way, the Pascal compiler catches some MAMake errors that the C++ compiler won't.
Hard copy? Hundreds of pages have been written about C++ and MacApp. The most useful, in my opinion, is Appendix E of the MPW C++ reference, entitled "MPW C++ Style Guide." In 35 pages, the essentials of C++ programming are set forth. It's not a tutorial; it's the sort of thing that's helpful in this kind of total immersion learning. It isn't theoretical and analytic; if you want to know why things work the way they do, consult the other (excellent) reference materials, including those mentioned above.
C++'s flexibility does allow typos to pass into compiled code a little more easily than in Pascal. But on the whole, while I realize there are critical differences between Pascal and C++- particularly when you examine how the languages actually run-from a user's point of view, both seem to serve well for implementing MacApp applications.
While my "total immersion" method may not work for everyone, I do think it's worth a try. Its prime advantage, at least to one who is as untheoretical as I am, is that it causes you to spend your time developing software rather than discussing it or reading about it.




