[net.lang.c] C compiler for pdp-11 under RSX

boylan@dicomed.UUCP (Chris Boylan) (06/03/84)

First, I am sorry this is so long.

I know of three C compilers available for RSX.  I would appreciate it
if people would post something if they know of others.  We use the
Whitesmith C compiler here but are not terribly happy with it.

This information is less than six months old.

The worst is the Telecon C compiler available from:
	TELECON SYSTEMS
	1155 Meridian Ave., Suite 218
	San Jose, CA 95125
	.
	.
	.
	Unfortunately, after examining your product we have determined that it
	is unacceptable.  It contains numerous bugs that showed up with casual
	use.  In addition the code generated seems well suited to an eight bit
	processor but is very inappropriate for a sixteen bit machine with
	multiple registers.

Don't waste your time with it.  It is basically garbage in it's current form.

There is the DECUS C compiler, see your DECUS order book for more
info.  This compiler hasn't had a lot of work done on it recently
and has a few problems.  I worked on a 15K line C software package
and we had to switch to the Whitesmith C compiler eventually.  The
only thing I can remember about our problems right off hand is that
the floating point version we had was missing a file or it was just
plain wrong as distributed.  The problem was with doing floating i/o
and everything seemed alright computationally although we gave it
up before we did anything extensive with it.  We found at least one
bug in it (I don't have it written down) and a tendency to not
generate errors where it should have.  It is usable in non floating
point applications.

The Whitesmith C compiler preceeded itself with a bad reputation.
The people who I know who have used it complained it had quite a
few bugs in both the RSX version and the VMS version.  I/they don't
remember what they were, except that the VMS version didn't convert
floats to ints right in coersion, something like that.

I dislike their requirement that all global data be initialized to
work but worse than that, they don't flag it if you don't initialize
it which means you don't notice it until you try to link it.  This
is a real pain in the butt if your working with a lot of code ...

Their coding style and thus their documentation is non-standard
and they typedef EVERYTHING to a bunch of stupid names. (reverse flames
to /dev/null.)  The code generated isn't very compact but at least
the thing is usable.  The pointer/array bug was a real bitch to
fix in our code which we did mostly under UNIX first.  It in someways
reflects a mistake in our coding style, but still it should have worked.

Here are a few bugs from the Whitesmith C compiler:

Whitesmith C Compiler Bugs.

The first of these is with the 'switch' statement.  Namely
the compiler does not detect a syntax error for the following case :

[this seems to be legal from net.lang.c but it should still issue
a warning that the code is unreachable, shows the dangers of Y+P in vi]

	switch(v) {

	S1;

	case L1:
		S2;
		break;

	case L2:
		S3;
		break;

	...
	}

the statement 'S1' is not flagged as syntactically bad.


Another bug in generated code also comes from the 'switch' statement.
The 'default' label must have at least ONE statement, even if it is only a
break.  If nothing is present, incorrect code is generated.



The third bug comes from a result of interchanging arrays and pointers.
(Although the C programming Manual specifically has an example to
show that this is indeed permissible)

The declartions

	extern TYPE v[];
           and
	extern TYPE *v;

causes the WHITESMITH compiler to generate DIFFERENT code.  Namely
if we have

	extern TYPE	v[];

	....

	p = v;

the code generated is  MOV #v,p
which is what one would expect.

whereas if we have

	extern TYPE	*v;
	....
	p = v;

	we get		MOV v,p
which is NOT what one would expect.
-- 

	Chris Boylan
	{mgnetp | ihnp4 | uwvax}!dicomed!boylan

boylan@dicomed.UUCP (Chris Boylan) (06/04/84)

I have to do a 1984 and unsay something.  In my original article
on the Whitesmith C compiler I mentioned a problem we had with
external declarations and compatiblity between pointers and arrays.
Simply hordes of people have been sending me mail telling me that
they aren't compatible and that I'm confused, some less politely
than others.

While I, and the person I worked with on the project, remember
testing the code involved we cannot remember the specific problem.
As we remember it, the code did work correctly on UNIX but generated
a garbage assignment on RSX using the Whitesmith compiler.  It is
unfortunate that that document I ~r'ed in was written after the
fact since the macro code was obvious correct for the pointer/array
question.

Since I cannot offer definitive proof that we weren't doing something
goofy, I will unsay what I said, if you follow what I mean.
Sorry for the confusion.

As to my contention that the Whitesmith C compiler was somewhat lacking
in optimization, it was clear from comparing the .s output that
it didn't do any significant amount of optimization.

If they used different csav/cret's for procedure calls we would
never have noticed it for the obvious reason.
-- 

	Chris Boylan
	{mgnetp | ihnp4 | uwvax}!dicomed!boylan

stein@druny.UUCP (SteinDW) (06/04/84)

I have had bad experiences with the Whitesmith C compiler under
RT-11.

First, relatively small modules of code (200-250 source lines)
would not compile. Pass 2 complained of no memory space. This made
partitioning of the program into inconvenient modules a neccesity.

Second, the "open" function destroyed the "onexit" (Whitesmith
added function) chain making the Whitesmith exit handler practically
useless (unless you opened EVERY needed file before intializing
the exit handler).


				Don Stein

"Aiko-Aiko"

andrew@orca.UUCP (Andrew Klossner) (06/05/84)

	"I believe they [Whitesmiths] may also be removing the
	requirement that all extern storage definitions (not
	declarations) be initialized exactly once among all load
	modules."

They can't.  Remember that Whitesmiths' original claim to fame was in
providing C compilers for a great many machines running operating
systems other than Unix.

On many systems, the loader doesn't speak COMMON blocks and requires
that a single module (file) EXPORT a symbol and that all other modules
IMPORT it.  When compiling C code a file at a time, there is no way to
do this with the existing language definition.

The language mod allows a global symbol to be EXPORTed when
initialized, IMPORTed when not initialized.  I can't think of a
language change which is much less painful and which will satisfy this
class of linkers.

  -- Andrew Klossner   (decvax!tektronix!orca!andrew)      [UUCP]
                       (orca!andrew.tektronix@rand-relay)  [ARPA]

dan@idis.UUCP (06/06/84)

A mild defense of Whitesmith's C compiler:

I have been using a slightly old version of the Whitesmiths
C compiler for several years.  I have stumbled across a few
circumstances in which it generates bad code, but for the
most part it does just fine.  I have occaisonally investigated
other people's complaints about Whitesmith's C and have often
found that the compaints were about behavior that was unexpected
but not actually wrong.  For example, Whitesmith's C requires
that global variables be initialized in one source file.  This
is really a requirement of the RSX task builder (the  RSX linkage
editor) and I cannot fault Whitesmith's C for using the standard
RSX task builder.  Other typical complaints are about the
Whitesmith's I/O library (not like the UNIX "standard I/O
library") or the C preprocessor (allows at most one include file
library directory; does not understand "../").  Gee guys, If you
wanted UNIX you should have bought UNIX (instead of RSX).

The worst thing I would say about the Whitesmith's C compiler
for RSX is that it doesn't always complain about bad source
code (garbage in ... garbage out) and is a little bit
version 6ish.

I have had much worse experiences with the DECUS C compiler
(thought pointer variables took up zero bytes and didn't
understand that casts implied conversion; no macros with
arguments!).  I believe some of these problems have been
fixed.  Does anyone know where I can get a current version
of the DECUS C compiler?  I want to use it with my RSX emulator
to build RSX binaries on my UNIX system.  Everything I get
directly from DECUS seems to be out of date.  Does anyone
know of a public domain task builder for RSX?

				Dan Strick
				[decvax|mcnc]!idis!dan
				(412) 624-2135
				(412) 624-5218

henry@utzoo.UUCP (Henry Spencer) (06/08/84)

In regard to the following commentary:

   	"I believe they [Whitesmiths] may also be removing the
   	requirement that all extern storage definitions (not
   	declarations) be initialized exactly once among all load
   	modules."
   
   They can't.  Remember that Whitesmiths' original claim to fame was in
   providing C compilers for a great many machines running operating
   systems other than Unix.
   
   On many systems, the loader doesn't speak COMMON blocks and requires
   that a single module (file) EXPORT a symbol and that all other modules
   IMPORT it.  When compiling C code a file at a time, there is no way to
   do this with the existing language definition.
   
   The language mod allows a global symbol to be EXPORTed when
   initialized, IMPORTed when not initialized.  I can't think of a
   language change which is much less painful and which will satisfy this
   class of linkers.

If you read the C Reference Manual, section 11.2, carefully, you will
see that there is already a solution to this problem present in C.
It does *not* require language changes, and it does *not* require the
misuse of initializers.

NB The C.R.M. I'm looking at is the one in the back of the K+R book;
anything much older may not show the same statement.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

alan@allegra.UUCP (Alan S. Driscoll) (06/10/84)

> On many systems, the loader doesn't speak COMMON blocks and requires
> that a single module (file) EXPORT a symbol and that all other modules
> IMPORT it.  When compiling C code a file at a time, there is no way to
> do this with the existing language definition.

As Henry Spencer has already pointed out, the definition of C doesn't
require that unitialized data be made common, although many existing
compilers do this.  (I know, some sloppy code depends on it.)

To export a symbol, you say something like

	int foo;

To import it, you say

	extern int foo;

There really isn't any problem.
-- 

	Alan S. Driscoll
	AT&T Bell Laboratories

chris@umcp-cs.UUCP (06/11/84)

I agree with this:

	From: alan@allegra.UUCP (Full Name Has Been Stripped By Bugs)
				(but it was Alan S. Driscoll)

	To export a symbol, you say something like

		int foo;

	To import it, you say

		extern int foo;

	There really isn't any problem.

My question:  is the following legal?

    extern int foo;
    .
    .
    .
    int foo;

(Within the same file.)  How about if the order is reversed?

I know of no machine's loader format, no matter how bizarre, that
could not handle this (after all, you can always have the compiler
set up to effectively say ``if I see a non-extern declaration
anywhere in the source, allocate space for the variable; if not,
"import" it'').  But there is apparently at least one machine out
there whose C compiler rejects this.  Can I simply declare that
machine's compiler to be incorrect, or do I have to resort to
the ``#define extern'' haque?

[A ``hack'' is a hack, but a ``haque'' is an Elegant Hack. :-)]
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

adm@cbneb.UUCP (06/12/84)

#R:allegra:-252500:cbnap:16200003:000:953
cbnap!whp    Jun 12 09:09:00 1984

>> Is the following legal?
>> extern int foo;
>> ...
>> int foo;

Its not only legal, but required in some cases.  I once wrote a bit of
C code that recognized certain keywords and for each one executed a different
routine.  This was best done by an array of structures, each element
containing the keyword (as a string) and a pointer to the appropriate
function.
The point is, to create the table, the functions had to be previously delcared.
Since the table needed to be defined at the top of the C source file,
to following syntax was needed:

extern int x(), y(), z();
struct
{
    char *keyword;
    int (*function)();
} table[] = 
{
    "word1", &x,
    "word2", &y,
    "word3", &z
};
. . . 
int x(...) {...}
int y(...) {...}
int z(...) {...}

The basic rule to remember for this type of stuff is, it is legal to
define something once, and it is legal to delcare it many times.  I
think any compiler that rejects this should be called incorrect.

minow@decvax.UUCP (Martin Minow) (06/13/84)

Chris Torek (umcp-cs!chris) asks: "Is the following legal:

	extern int foo;
	...
	int foo;

or vice-versa."

Yes (both ways) in Decus C, which emits global references when
the file has been fully compiled.

I think this fails on Whitesmith's compilers (though I haven't checked).
However, the following should always work:

	extern int foo;
	...
	int foo = 0;	/* Explicit initialization */

Here is a more difficult problem:

	func() {
	    extern char *localfunc();
	    ...
	}

	static char *
	localfunc() {
	    ...
	}

The above will not work correctly per the draft Ansi standard as
the "globalness" of localfunc() was set by the *first* reference.
Thus, localfunc() is global to all functions.  The draft (and many
existing compilers) permit you to write:

	func() {
	    static char *localfunc();
	...

I believe that this is an error (i.e. that the local/global
distinction should be made by the defining instance), but the
standards committee seems to want to make things easier for the
people who want to write one-pass compilers.

Martin Minow
decvax!minow