Path: utzoo!yunexus!geac!syntron!jtsv16!uunet!ncrlnk!ncrcae!hubcap!gatech!rutgers!apple!bionet!agate!violet.berkeley.edu!pete From: pete@violet.berkeley.edu (Pete Goodeve) Newsgroups: comp.sys.amiga Subject: C++ (Lattice) -- First impressions... Keywords: C++,review Message-ID: <16021@agate.BERKELEY.EDU> Date: 26 Oct 88 07:52:13 GMT Article-I.D.: agate.16021 Sender: usenet@agate.BERKELEY.EDU Reply-To: pete@violet.berkeley.edu (Pete Goodeve) Organization: University of California, Berkeley Lines: 139 I was one of those who jumped in and bought Lattice C++ at Ami-Expo for the "bargain" price of $250. Having immersed myself intensively in it for a couple of weeks, I think it's about time to pass on my impressions. Most important, I guess, is that it seems to perform as advertised. I was mightily pleased that my early attempts to create some classes and matching test programs all seemed to run first time [once I'd gotten past all those pesky error messages, naturally]. I haven't noticed any bugs in the compiler yet (though it does seem rather more prone to "knock on" errors -- those hordes of spurious reports that follow a genuine mistake -- than regular Lattice C). On the other hand, it IS a bit of a pig. They recommend 1.5 Meg and a hard disk. (I have extra memory rather than the hard disk, and that seems to be reasonably good.) It has two precompile passes before the compiler proper (Lattice 4.1 at the moment) gets it, so no way is it going to be particularly speedy. As one illustration of its hoggish nature, take the two versions of "Hello World" in the examples directory: the first just uses a C++ "stream" for output rather than printf, the second opens a window to display the text. The stream version source is 89 bytes long: it generates an intermediate C file of nearly 6K... the executable is 14K! On the other hand, the executable of the window version is only 900 bytes longer than that, and in general more complex programs have more rational sizes. Obviously there's quite a bit of fixed overhead for things like the stream library. By far the most impressive thing about this implementation is that ALL the Exec and Intuition structures are now OBJECTS, with associated methods to manipulate them. For example, I was able to enclose the "Hello World" in the window with an ellipse by adding three statements (one to compute its size, one to position it, and one to draw it) -- and again it worked first time, except that I got the ellipse positioned wrong. On the flip side, I have one MAJOR nit to pick. There is NO way that I can find to redirect the error messages anywhere but the console! Trying a standard CLI ">" in the cc command has absolutely no effect, and there is no switch option to select an error file. You have to have a ready finger on the space bar to catch the early messages. Add in the knock-on effect I mentioned, and it becomes a real pain. + + + The package contains two disks (compiler+libs and includes+examples), a manual (with more than the occasional omission and error, but reasonable) and a textbook "An Introduction to Object Oriented Programming and C++" by Wiener and Pinson. Given that I was able to read the text all the way through without gibbering in frustration at any point, I guess I have to rate it as pretty good. It also doesn't seem to be too hard to find a particular bit of information that you need. They did manage to make it a little harder to read than it should have been by printing identifiers in the same font as the rest of the text; as they had chosen nice meaningful names for these, sentences could get rather confusing. Also I've reached the conclusion that it's not a complete description of all the C++ features. Luckily I had Stroustrup's article in IEEE software handy to clear up some points; I probably will have to get his book for the final word. The examples included on the disk look interesting, but to be truthful I haven't played with them yet. I'm always more interested in trying out experiments of my own. I have noticed though that the comments in the examples are in the conventional C programming style -- largely missing... + + + All in all I find C++ itself a real pleasure. At the very least, with things like overloading of operators, anonymous unions, reference parameters, and so on, it is a large step beyond vanilla C. Its "Object Oriented" features -- classes and so on -- are very powerful additions which seem easy to use. I do have one important quibble about this aspect, though, which I'll return to in a moment. And I did have an unexpected adventure or two along the way. As an exploratory mission, I thought I would implement a true "string" type (i.e. "class") -- one that manages its own storage dynamically. [I'm sure that someone must have done this already, but my cursory search of the handy literature didn't turn one up, so I went ahead anyway.] The goal is a class such that you can say: string s1, s2; s1 = "some text"; s2 = "..more text"; s1 = s2; s1 += "...append this" /* ... and so on */ and each time you change the contents of a string it will allocate new storage and discard the old automatically. I won't go into the details. Suffice to say that it all went together very easily. I got surprised by one feature of C++ here, which in fact could be a potentially serious Ooh-Nasty. What happened was that my first string assignment test (s1 = "a string";) worked perfectly, but I stopped congratulating myself when I found that I had forgotten to actually define the "=" operator in my string class!! Basically it seems that the "constructor" you define for a class will also by default be used as a cast function in an assignment to that class. This meant that storage for the string was being allocated properly; on the other hand the corresponding "destructor" ISN'T invoked on any data that might happen to be already in the string, so THAT block would be cast adrift, never to be recovered. Ouch. My big gripe, though, is that C++ makes a big deal about its "Object Orientation" and "Data Hiding", but to my way of thinking it doesn't really meet those qualifications very well. I'm probably more of a "Data Hider" than an "Object Lover", so I was looking forward to creating classes where I could wall off the implementation from the user modules. The reason is not just to hide my bad code, but so that I could CHANGE the representation if I wanted to WITHOUT having to recompile all the user modules, as long as I didn't modify the public interface of the class. For example, one might want to change a "stack" class from an array storage implementation to a linked list, leaving the "push()" and "pop()" etc. the same. Actually a couple of remarks in the references suggest one should be able to do this, but I made a quick check and the Guru gave me his True Word immediately: You CANNOT change the private section of a class and expect it to run with the old user modules. In fact, I can't see how it could be otherwise. The only indication of how much storage a class needs, for instance, is in its definition, so wherever a module invokes a "new" operation for the class it must have the complete information in the header file. You would need to actually store the information in the executable file somewhere -- and how would you know which information to store if not all the headers were the same? Maybe some other implementation has solved this somehow, but as the Lattice version comes straight from AT&T I doubt it. Oh well. It ain't perfect, but it's getting there. What I like the most is that it provides all these neat features without being dogmatic about it (a true descendant of C...). You can write code for your program at whatever level seems appropriate. There is one other language that I would even more like to see on the Amiga [POP-11, if you must know], but until that comes along, I think C++ may keep me pretty satisfied. -- Pete -- ... and, yes -- the list price ($500) SHOULD be lower.