[comp.lang.c] Which C compiler: TC or MS?

asylvain@felix.UUCP (Alvin E. Sylvain) (09/26/90)

In article <4641@feldspar30.UUCP> nellis@motcid.UUCP (Michael R. Nellis) writes:
>I am looking to purchase a 'C' compiler.         [...]
>the Microsoft 5.0 C compiler with QuickC and     [...]
>a factor?  Money is not an issue here, support,
>and functionality is.                            [...]
[[[ muchly deleted, of course ]]]

(Please excuse first-time contributor if he happens to F Up Beyond All Repair)

In all the fuss over C compilers for the PC, not much mention is made
of a small, inexpensive C compiler from a company called MIX, called
Power C.  Someone besides me must have tried it, and have an opinion!

It has gotten favorable media reviews, costs relatively nothing,
($19.95, use your own editor) is very, *very* fast, very, *very*
comprehensive, and 99% ANSI compliant (according to reviews).  It out-
performs Turbo C (very fast reputation, well deserved) in some
independent speed benchmarks, including compilation and execution times.

Even without the compiler, the included manual is _well_worth_ the price.

I find it *quite* satisfactory.  A couple of reviews mentioned a lack
of large memory model, which is *not* correct; the latest versions *do*
support the large memory model, which I have used successfully.

If you are willing to shell out a few hundred bucks for a C compiler,
another 20 won't hurt much.  You might as well try out the cheap one
before you shell out the BIG bucks.  If you don't like it, consider
yourself to have bought an *excellent* manual and C tutorial.

SUPPORT: I reported a bug in an earlier version; they sent me a library
source code patch for it, since I had purchased the library source code.
I can't vouch for their support otherwise, having had no other problems.

DISCLAIMER: I'm *not* an employee of MIX ... no relation whatsoever,
no advertising royalties (too bad) ... I don't like their debugger,
(sold separately).  I also don't like their integrated 'Project'
('make') utility (can't handle include file changes), but it does work.
Instead, I use a UNIX@ look-alike 'make' from shareware.

MIX also sells UNIX@ look-alike tools for MS-DOS, which I can't vouch
for (haven't tried).  But it's attractively priced (read: CHEAP), and
does include a 'make' utility.

@ lest we forget, UNIX is (or was) a registered trademark of AT&T :-)
========================================================================
"I got protection for my    |               Alvin "the Chipmunk" Sylvain
affections, so swing your   |   Natch, nobody'd be *fool* enough to have
bootie in my direction!"    |   *my* opinions, 'ceptin' *me*, of course!
========================================================================

raymond@math.berkeley.edu (Raymond Chen) (09/30/90)

A summary of articles discussing "Which C compiler for the IBM PC
should I buy?" is available for anonymous ftp from math.princeton.edu
[128.112.128.157] as the file pub/rjc/csip/compilers.Z.  I try to
keep it up to date, but the recent rash of discussion has yet
to be added to the list.  (For people who can't email, send a message
to rjc@math.princeton.edu with a blank subject line, and containing
as the body the single line "send compilers" (no quotation marks).  Do
not append a signature.)

mitchell (Bill Mitchell) (10/01/90)

In article <151565@felix.UUCP> asylvain@felix.UUCP (Alvin E. Sylvain) writes:
>
>In all the fuss over C compilers for the PC, not much mention is made
>of a small, inexpensive C compiler from a company called MIX, called
>Power C.  Someone besides me must have tried it, and have an opinion!
>

I tried it when it first came out.  I recall that it had a VERY nice
debugger included, and that it used its own unique object file format
(something other than .obj files).  I remember being impressed overall
and putting it back on the shelf because of the incompatable object file
format, and maybe because of a runtime library missing functions I
was used to having.  MIX subsequently released a later version called
(I think) Power-C, which I bought but never installed.

>Even without the compiler, the included manual is _well_worth_ the price.

I remember thinking the same thing.

catfood@NCoast.ORG (Mark W. Schumann) (10/03/90)

In article <151565@felix.UUCP> asylvain@felix.UUCP (Alvin E. Sylvain) writes:
>>Money is not an issue here, support,
>>and functionality is.                            [...]
>In all the fuss over C compilers for the PC, not much mention is made
>of a small, inexpensive C compiler from a company called MIX, called
>Power C.  Someone besides me must have tried it, and have an opinion!
>I find it *quite* satisfactory.
>If you are willing to shell out a few hundred bucks for a C compiler,
>another 20 won't hurt much.  You might as well try out the cheap one
>before you shell out the BIG bucks.  If you don't like it, consider
>yourself to have bought an *excellent* manual and C tutorial.
>SUPPORT: I reported a bug in an earlier version; they sent me a library
>source code patch for it, since I had purchased the library source code.
 
   I've posted in the past my complaints about some cryptic error
   messages coming out of the Power C compiler/optimizer phase.
   Here's an example of what I'm talking about.  Perhaps someone
   out there in net-land can help me out.  (Or we could establish
   alt.powerc to beat the subject to death?)  I do have to point
   out again that Mix Software's tech people don't seem to be very
   helpful on questions like these.  I am posting this to get some
   assistance with the problem, but also in case it proves unfixable
   to warn others about what can happen if you push Power C too hard.
 
   The situation is this: I am working on an IBM PC-compatible
   screen I/O library, of course using direct screen read/write
   when possible.  To avoid CGA chromablizzard problems, I intend
   to use two sets of read/write functions.  For CGA monitors,
   the functions are called $CgaPeek() and $CgaPoke(); otherwise, I
   want to use $MonoPeek() and $MonoPoke().  To call those functions,
   I use function pointers $Peek() and $Poke(), which are set to the
   CGA functions (when necessary) or the Mono functions.  I plan
   to test for a CGA monitor by calling function $isCGA(), but at
   this point it is a stub function that always returns zero.
 
   My library consists of three source files.  DAZZPRIM.C contains
   the source for the "primitive" functions, whose names begin with
   the dollar sign and which should be called only from functions
   in this library.  DAZZ.C contains higher level functions such as
   clear(), say(), set_attr(), and so on.  Finally, I'm implementing
   an analogue of the Clipper achoice() function in file ACHOICE.C.
 
   I am using a Power C project file named DAZZ.PRJ to compile each
   source file and combine the objects into the library DAZZLIB.MIX.
   Here's what Power C gives me:
 
------------------------------------------------------------------------------
 
D:\DAZZ> PC DAZZ
Power C - Version 2.0.0
(C) Copyright 1989 by Mix Software
Project: dazz.PRJ
No errors detected           <<< compiling dazzprim.c >>>
No errors detected           <<<           dazz.c     >>>
No errors detected           <<<           achoice.c  >>>
New library: dazzlib.MIX
 3027 lines compiled
Optimizing ...
$isCGA       Invalid object tag      <<< What's this??? >>>
achoice  Errors detected
   34 functions optimized in 3 files
 
D:\DAZZ>
 
------------------------------------------------------------------------------
 
   My question for the Mix people, and now for you, is:
 
      1. What's an object tag?
      2. Why is it invalid?
      3. What can I do to fix it?  (If I have to modify
          the source, that's okay.)
 
   The source of ACHOICE.C, with blank lines omitted, is as follows:
 
------------------------------------------------------------------------------
 
#include "dazz.h"
#include <bios.h>
#include <conio.h>
#include <stdarg.h>
#include <stddef.h>
char userkeys[] = {ESCAPE, LEFT, RIGHT, HOME, END, ENTER, 0};
/*=======================================================================
achoice--
  Clipper-style Achoice() function.
=======================================================================*/
int achoice (
    int win_top,
    int win_lft,
    int win_btm,
    int win_rgt,                  /* Window top-bottom-left-right */
    char *options[],              /* Null-terminated string array */
    unsigned int argflag, ... )   /* 1 = toggles follow; 2 = userfunc */
{
int win_hgt, win_wid;
int start = 0, current = 0, m = 0;
register int k;
unsigned count;
INDICATOR flag = repaint;
ATTRIB cursor_color = REVERSED;
ATTRIB normal_color = $GetAttrib();
/* Optional arguments */
va_list argptr;
int *toggles;
USERFUNC UserFunc;
char s[80];
toggles = NULL;
UserFunc = NULL;
  /* Get the optional arguments */
  va_start (argptr, options);
  if (argflag & 0x01) toggles = va_arg (argptr, int);
  if (argflag & 0x02) UserFunc = va_arg (argptr, USERFUNC);
  /* Count the array elements */
  for (count = 0; options[count] != NULL; count++);
  /* Get window height and width */
  win_hgt = win_btm - win_top + 1;
  win_wid = win_rgt - win_lft + 1;
  while (flag == none || flag == repaint) {
    if (flag == repaint) {
      /* bang top of window */
      if (current < start) {
        start = current; /* cursor to top of window */
        if (UserFunc != NULL)
          flag = $UserFunc (UserFunc, 1, options, &current, start, k);
        }
      /* bang bottom of window */
      else if (current >= start + win_hgt - 1) {
        start = current - win_hgt + 1;
        if (UserFunc != NULL)
          flag = $UserFunc (UserFunc, 2, options, &current, start, k);
        }
        { register int i;
      /* repaint the window */
      for (i = 0; i < win_hgt; i++) {
        if (options[i] == NULL) break;
          clear_attr (win_top + i, win_lft, win_top + i,
             win_rgt, global_colors.standard);
          say_attr (win_top + i, win_lft, options[start+i],
           (toggles == NULL || toggles[start+i] ?
           global_colors.standard : global_colors.unselected));
        flag = none;
        } }
    highlight (current - start + win_top, win_lft, win_wid);
    /* Keyboard is idle for a sec */
    flag = $UserFunc (UserFunc, 0, options, &current, start, k);
    k = $Inkey();
    if (UserFunc == NULL && isalpha (k))
      m = $ScanChoice (options, current, k);
    else if (UserFunc == NULL)
      switch (k) {
        case UP:        m--;    break;
        case DOWN:      m++;    break;
        case HOME:
        /* case CPAGEUP: */  m = 0;    break;
        case END:
        /* case CPAGEDN: */  m = count - 1;  break;
        case PAGEUP:    m -= win_hgt;  break;
        case PAGEDOWN:  m += win_hgt;  break;
        case ENTER:     flag = chosen;  break;
        case ESCAPE:
        case LEFT:
        case RIGHT:     flag = quit;  break;
        }
    /* Keystroke exception: User-function called with `3' argument */
    else if (isalpha (k) || (strchr (userkeys, k) != NULL))
      flag = $UserFunc (UserFunc, 3, options, &current, start, k);
    else switch (k) {
      case UP:
        m--;
        break;
      case DOWN:
        m++;
        break;
      case PAGEUP:
        m -= win_hgt;
        break;
      case PAGEDOWN:
        m += win_hgt;
        break;
      }
    if ((flag == none) || (flag == repaint)) {
      /* My submission to the obfuscated code contest...           */
      /* Purpose: 1) flag set to repaint if outside current window */
      /*          2) m set within range 0 to count -1 inclusive    */
      flag = (m <= start || m >= start + win_hgt - 1) ? repaint : none;
      m = (m < 0) ? 0 : (m >= count) ? count - 1 : m;
      /* Now unhighlight what was formerly the `current' item. */
      if (m != current) {
        unhighlight (current - start + win_top, win_lft, win_wid);
        current = m;
        }
      m = current;
      }
    }
  switch (flag) {
    case chosen:  return current;    break;
    case quit:    return -1;         break;
    case error:   return -1;         break;
    default:      return -1;         break;
    }
  }
}
/*=======================================================================*/
INDICATOR $UserFunc (
      int (* UserFunc)(),
      int status,
      char **array,
      int *current,
      int start,
      int lastkey )
{
  if (UserFunc == NULL)
     return none;
  else {
    switch (UserFunc (1, current, current - start)) {
      case 0:  /* abort selection, returning zero */
        return quit;
        break;
      case 1:  /* return current value */
        return chosen;
        break;
      case 2:  /* continue selection process */
        return none;
        break;
      case 3:  /* go to the next item whose first        */
        /* character matches the last key pressed */
        current = $ScanChoice (array, current, lastkey);
        return none;
        break;
      default:  /* error: user function should return only */
            /* zero, one, two, or three!               */
        return error;
      }
    }
  }
/*=======================================================================*/
int $ScanChoice (char **array, int begin_point, int keyvalue)
{
int x;
  x = begin_point;
  do {
    x++;
    if (array[x] == NULL) x = 0;    
    if (toupper (array[x][0]) == toupper (keyvalue))
      return x;
    } while (x != begin_point);
  return begin_point;
  }
/*=======================================================================*/
 
 
   That's all.  If anyone can help with this (which sure looks like
   a compiler bug), please post or e-mail me.  Thanks to all.
 
----------------------------------------------------------------
 Mark W. Schumann\3111 Mapledale Avenue\Cleveland OH 44109 USA
 UUCP: ...!mailrus!usenet.ins.cwru.edu!ncoast!catfood
 Internet: catfood@ncoast.org
 "The AS/400 is for people who move their lips when they type."
----------------------------------------------------------------
-- 
============================================================
Mark W. Schumann  3111 Mapledale Avenue, Cleveland 44109 USA
Domain: catfood@ncoast.org
UseNet: ...usenet.ins.cwru.edu!ncoast!catfood
============================================================

matthew1@stretch.cs.mun.ca (Matthew J. Newhook) (10/05/90)

catfood@NCoast.ORG (Mark W. Schumann) writes:

[text deleted...]
>------------------------------------------------------------------------------
> 
>D:\DAZZ> PC DAZZ
>Power C - Version 2.0.0
>(C) Copyright 1989 by Mix Software
>Project: dazz.PRJ
>No errors detected           <<< compiling dazzprim.c >>>
>No errors detected           <<<           dazz.c     >>>
>No errors detected           <<<           achoice.c  >>>
>New library: dazzlib.MIX
> 3027 lines compiled
>Optimizing ...
>$isCGA       Invalid object tag      <<< What's this??? >>>
>achoice  Errors detected
>   34 functions optimized in 3 files
> 
>D:\DAZZ>
> 
>------------------------------------------------------------------------------
> 
>   My question for the Mix people, and now for you, is:
> 
>      1. What's an object tag?
>      2. Why is it invalid?
>      3. What can I do to fix it?  (If I have to modify
>          the source, that's okay.)
> 

I'm no mix person, but I would bet that the problem is caused by you using
a $ in the function name.  Try calling them something else...
-- 
----------------matthew1@stretch.cs.mun.ca 
"Living in the limelight; the universal dream for those who wish to 
seem. Those who wish to be must put aside the alienation, get on with 
the facination, the real relation, the underlying theme" - Rush

alanf@bruce.cs.monash.OZ.AU (Alan Grant Finlay) (10/06/90)

In article <1990Oct3.154752.6996@NCoast.ORG>, catfood@NCoast.ORG (Mark W. Schumann) writes:
>    I've posted in the past my complaints about some cryptic error
>    messages coming out of the Power C compiler/optimizer phase.
>    Here's an example of what I'm talking about.  Perhaps someone
>    out there in net-land can help me out.  (Or we could establish

I think you will be lucky to get anyone to solve this for you.  You have 
included too much information.  My (and probably the standard) practice in
this sort of situation (an incomprehensible error message from a compiler) is
to use a divide and conquer approach.  If you think you know which module the
"error" is in then replace the other modules with stubs so we can be sure.
Now if the error is still there then start cutting the culprit module in half
until you have the minimal set of statements that still cause the "error"
message.  Usually by now you will have discovered what the problem is.  If
not try changing the names of any identifiers that might be given another
interpretation or even all the identifiers just in case.  If you still have 
an "error" then let us know.  In some cases this strategy does not work 
(for example there is a bug in the compiler which generates a "random" error
message when the 1024th source line is over 60 characters long).  The strategy
depends upon the fact that such bugs are not USUALLY very context dependent.
You cannot expect to generate the error message with just one segment of the
original - there is usually some context sensitive aspect.  Hence you 
eventually have to work very painstakingly - rather like digging up an
archeological relic.  When you finaly advertise a four line program that is
obviously correct and causes the message you can expect to get the implementor's
attention pretty quickly - such people are really quite proud of their work.

N.B. Have you tried an alternative compiler?  (Just in case!)
N.N.B. If your complaint is simply that you expect better error messages then
consider the following quotation: "Any fool can write a compiler for correct
programs" - J.S. Rohl.  It is really really hard to anticipate every form of
error in a source program and provide meaningfull diagnostics.  Consider
how lucky you are that your compiler doesn't just have 3 error messages like
some I have heard of.