home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 14 Text
/
14-Text.zip
/
proscons.zip
/
highc33.txt
< prev
next >
Wrap
Text File
|
1995-01-12
|
15KB
|
298 lines
You may recall that some months ago I first encountered Metaware High C++
3.2a for OS/2, and reviewed it for you all. Well, Metaware is now
shipping version 3.31 of High C++ for OS/2, which includes several
changes, and I have upgraded. So it's time for another of my occasional
product reviews.
Metaware High C++ is an ISO Standard C and C++ compiler, with versions
available for platforms ranging from OS/2 through AIX to DOS. High C++
for OS/2 has all of the jazz that you would expect of a professional OS/2
C++ compiler. It ships with the OS/2 Developers' Toolkit as part of the
package, and all of the tools are native 32-bit OS/2 programs. If you
have IBM's WorkFrame/2, you can use it to drive High C++, as all of the
necessary "glue" is supplied.
High C++ ships with Rogue Wave's Tools.h++ class library (and accompanying
manual). RW Tools.h++ is a cross-platform set of C++ classes, covering
everything from multibyte strings to file-based BTrees. Most of the
container classes come in both SmallTalk style and template style
versions.
One of the things that I like about High C++ itself is the quality of its
manuals. Programmers like Good Printed Documentation(tm). The High C++
manuals qualify. They are very clear and concise, being sensibly divided
into a Language Reference for general C++ stuff, a Programmer's Guide
dealing with the details of running the actual compiler on OS/2, a Library
Reference dealing with the run-time library (with non-ISO, ISO, and
extra-ISO functions clearly distinguished), a DirectToSOM Developer's
Guide dealing with using DTS C++, and so on. They are excellently indexed
as well. Someone at Metaware knows how to use a permuted index tool.
Of course, one of the most important things about any compiler is how well
it actually compiles code, and how good its language implementation is.
In terms of speed and system requirements, High C++ is not as fast as
Borland C++ (which is still the least hungry OS/2 C++ compiler), but it is
definitely less weighty than IBM CSet++. The documentation states 10Mb
RAM and 16Mb hard disc (Borland's says 8Mb RAM and uses 20 Mb hard disc)
and I'm here to tell you that it works well in 20Mb RAM (smug grin).
The High C++ optimiser has no less than eight levels. Each individual
optimisation, ranging from dead code elimination through instruction
scheduling to loop unrolling, can be selectively enabled or disabled,
either by compiler toggles on the command line or by pragmas.
The compiler will generate code specifically for the 386, 486, or 586
processors, and uses OS/2's floating point support. Like all other
compilers for Intel CPUs you can also select non-ANSI floating point use
when speed is more important to you than strict ANSI handling of errno.
High C++ even has a second optimiser : a multi-file inliner which can be
run during compiliation. This is capable of inlining way more than the
standard optimiser, including inlining functions in one file that are
defined in another.
Another thing that came as a pleasant surprise with High C++ was the
usefulness of the compiler error messages (which can be configured if you
are using tools that expect messages in a specific format). A lot of the
C++ error messages refer you to the relevant pages in the ARM. Some of
them are very verbose. Incorrect use of an overloaded function gives a
list of all the possible overloaded variants on that function, for
example.
But this is perhaps the best one :
[c:\temp]type error.cpp
enum planet { JUPITER, SATURN, URANUS } ;
int main ( int, char ** )
{
planet t = SATUNR ;
return 0 ;
}
[c:\temp]hc error.cpp
MetaWare High C/C++ Compiler R3.31@1
(c) Copyright 1987-94, MetaWare Incorporated
E "error.cpp",L6/C11(#222): SATUNR
| Identifier is undeclared; assuming `SATURN' instead.
1 user error No warnings
Metaware takes great pains to be right up to date in its compiler with
respect to the currently evolving C++ standard, and supplies a host of C++
features, such as namespaces, Run-Time Type Information, exceptions,
exception-aware classes, templates, nested classes, and dynamic casting.
Namespaces are a feature new to C++ whereby related classes and variables
can be grouped into a namespace of their own, so that they won't conflict
with other classes and variables of the same name. The ability to make
C++ classes exception-aware allows you to ensure that instances of your
classes are properly cleaned up when a C++ exception is thrown. High C++
is the only retail compiler for OS/2 to offer such features. As far as I
am aware it is in fact the only retail compiler for any platform to do so.
Of course, some C++ language features involve implementation complexities,
which can make any programmer's life difficult. One such problem is the
"single-copy problem" for template instances and virtual function tables.
High C++ offers you two routes to overcome this problem. You can either
explicitly direct which module of your application will contain which
template instance or virtual function table, or High C++ can link the
application in such a way that multiple copies of a template instance or
virtual function table from separate object files are overlaid to produce
a single copy in the final executable.
Unlike some other ISO C and C++ compilers, which usually offer the ability
to compile either C or C++, High C++ offers varying degrees of C and C++,
known as "Incremental strengths". These go from "plain C" which is ISO C,
through "weak C++" which is ISO C with all of the C++isms added that won't
break existing ISO C code, and "standard C++", which is C++ but allowing
vestigal Cisms, to "full C++" which is C++ with all of the rules strictly
enforced.
High C++ lets you control a lot of the things that are "left to the
implementation" by the standards, too. The default sign of char can be
changed between signed and unsigned, for example. The alignment and
padding of structures is also controllable.
High C++ even supports modifiable function calling conventions. You want
to call someone else's function that passes parameters left-to-right,
returns a floating point result on the stack, and cleans up the stack for
you upon return ? No problem squire.
High C++ also provides several "one step beyond ISO" optional extensions
to C++ that cover some areas outside of "standard" C++. Several of these
are simple extensions to C and C++ such as a "long long" integer type,
short and long enumerations, case ranges in switch statements, and numeric
literals in any base (bit manipulation is a lot easier when you can define
the bitmasks in binary, let me assure you).
Other High C++ extensions to C and C++ are more profound. High C++ allows
ADA-style pass-by-name function calling, MODULA-style nested functions,
and "for iterators" which are a generalisation of the idea of a for loop.
Another important enhancement to C++ is DirectToSOM C++.
SOM is IBM's System Object Model, a CORBA-compliant language-independent
foundation for classes and objects. It's already used by the Workplace
Shell on OS/2 (allowing WPS to be extended easily), and is the intended
basis for Taligent Application Frameworks. With most C++ compilers,
writing applications that use SOM involves complex and syntactically
obscure "language bindings" to allow you to use the SOM runtime.
Not so with DirectToSOM C++! DTS C++ allows you to declare and use SOM
classes in your code just as if they were ordinary C++ classes. You just
write C++ code. Flick a compiler switch when you compile (or change your
class definitions so that they derive from a SOM base class), and the
compiler itself handles all of the necessary conversion from C++ to using
the SOM runtime. Even I can use SOM when it is this easy!
SOM itself provides features not found in C++ but familiar to object
oriented programmers who use other languages, such as attributes and
metaclasses. DirectToSOM C++ allows you to use these with a minimum of
variation from normal C++. Accessing an attribute of a SOM class, for
example, is coded in identical manner to accessing an ordinary data member
of an ordinary C++ class.
Similarly, High C++ allows DTS C++ programmers to use features in C++ that
they may be used to, but which are not present in SOM, such as function
overloading, abstract base classes, and C++ exceptions. This is useful in
cases where the language independence of SOM is not a concern, but where
the increased separation between class use and class implementation that
SOM affords compared to ordinary C++ may be desired.
High C++ can also easily turn DirectToSOM C++ class definitions into IDL
for you. IDL is CORBA's language independent means of describing classes,
that be translated into language bindings for use with other languages.
Metaware co-developed DTS C++ with IBM, and has included it in High C++
since version 3.2. IBM is about to release CSet++ 3.0, which will be its
first DTS C++ compiler. I have obtained a pre-release copy of CSet++, and
it is not letting the cat out of the bag to confirm from my experience
that SOM binary compatibility works with DTS C++. A SOM class implemented
using DTS C++ in High C++ can be used, in DLL form and without reference
to the library source, by code written in DTS C++ in CSet++. What is
more, as long as the SOM rules are adhered to, either may be changed
without affecting the other. Binary compatibility across C++ compilers is
impossible with standard C++, and easy with DirectToSOM C++.
Anyone wanting to use C++ across compilers, or for large projects in a
single compiler where modules may need to be kept separate, should take
note. With DirectToSOM C++ the future may well have already arrived.
High C++ includes several features that are more specific to OS/2
development.
As with all OS/2 C++ compilers, the C/C++ run-time library is available as
a static library, or in DLL form. Compiling and linking a DLL of your own
is as easy as flicking one compiler switch. If you do not wish to worry
about entering mangled C++ function names into the DEF file, High C++ also
allows you to instead mark functions as "exported" in the source, using
__declspec(dllexport).
High C++ also provides full support for multithreaded applications. Of
course, the Standard C library is provided in a multithreadable form, and
compiling code that uses it is again a simple matter of flicking a single
compiler switch. Unusually for an OS/2 C++ compiler however, in High C++
the iostreams portion of the C++ run-time library can also be safely used
from multiple threads. What is more, High C++ allows you to declare your
own variables as thread-safe using __declspec(thread), and it will handle
keeping different copies of the same variable for each thread for you.
Since I have now been using High C++ for some time, I can comment on more
longer term aspects of High C++ than I could in my last review. I've been
able to throw quite complex code at the compiler, I have played around
with some of its features in greater depth, and I have also had experience
of Metaware's technical support.
Although I was initially slightly skeptical of some features, such as
nested functions and for iterators, they have been proven by the ultimate
test, which is that they turned out to be very useful in practice.
I can report that the tech support is excellent. When I discovered a
problem in DirectToSOM that gave the compiler indigestion (as I said, I
have been able to explore more of the boundaries of some features) the
folks at Metaware corrected the compiler and provided a free update.
There wasn't a hint of my having to wait until the next major update for
the bug fix.
There are weaknesses in High C++ of course. But not many. The debugger
(MDB) is text-mode and quirky (rather like Watcom's old WVIDEO), and
there's no IDE (apart from Workframe). But then again, some people prefer
their favourite programmer's editor (BOXER in my case) and makefiles...
As I said before, although High C++ is not perfect, I enjoy it. It is an
excellent compiler for the professional C++ programmer.
You may be put off by the high price compared to other OS/2 C++ compilers,
but then you have to ask yourself whether they include Rogue Wave's
Tools.h++, DirectToSOM C++, namespaces, exceptions, RTTI, for iterators,
nested functions, incremental strength C++, "one touch" DLL generation,
easy multithreading, ...
If you want to contact Metaware to find out more, here's the gen :
C u s t o m e r S e r v i c e MetaWare Incorporated
* 30-day money back guarantee 2161 Delaware Avenue
* 90-day warranty (free upgrade) Santa Cruz CA 95060-5706
* Free tech support by: phone, internet: techsales@metaware.com
fax, email, bulletin board tel: (408) 429-6382
* Major upgrades are chargeable fax: (408) 429-9273
» JdeBP «
» Jonathan de Boyne Pollard, FIDONET 2:440/4.0, JdeBP@donor2.demon.co.uk «
-----------------------------------------------------------------------------
Topical aside :
I have a Pentium at work, and when I learned of the bug in the Pentium
floating point division instruction, I was naturally interested in seeing
it for myself. So I compiled one of the widely circulated example
programs :
#include <stdio.h>
int main ( int, char ** )
{
double x = 4195835.0, y = 3145727.0;
double z = x - (x / y) * y;
printf("%f\n",z);
return 0;
}
This program should print 256.000000 on a Pentium, and 0.000000 on a 386
or 486.
When I first compiled it with High C++ 3.31a, it printed 0.000000 on my
Pentium, which was the wrong (i.e. correct) answer! When I looked at the
generated code using Metaware's debugger, I realised that High C++ had in
fact recognised that the calculations cancelled each other out, and had
optimised them away, reducing the program down to, in effect :
#include <stdio.h>
int main ( int, char ** )
{
printf("%f\n", 0.0);
return 0;
}
I hadn't even turned optimisation on. This was with the default
optimisation! Bypassing this did yield the correct (i.e. wrong) result
on my Pentium. So the bad news is, I suppose, that my Pentium is wrong
just like everyone else's. (-:
When I received the fix to the compiler for my DirectToSOM problem, I was
also told that Metaware plans to release a feature to fix problems caused
by FDIV, and that the update to the compiler that they were sending me
actually included a preliminary version of this feature.
So I nosed around a bit and found it. There's a new compiler toggle,
Pentium_safe_divide_code. When I turned it on, and recompiled the above
program, High C++ generated extra code around the FDIV instruction that
at runtime would replace it with a call to a library routine if necessary.
So (since my copy already appears to have it) it looks like Metaware is
going to be the first C++ compiler vendor to release a workaround for the
Pentium FDIV bug.