Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/nmit/cc-user.doc
There are no other files named cc-user.doc in the archive.
NMT V7 C Project
Compiler User Guide
June 1985
This document describes how to use the
Version 7 C compiler at New Mexico Tech, and
some of the peculiarities of the
implementation.
Operating System: TOPS-20
Software: V7 C v1.0
pppppppppppppppp
pp ppp
pp cccccccccc pp
pp cc cc pp
pp cc 7777 pp
pp cc 7 pp
pp cc 7 pp
pp cc 7 pp
pp cc cc pp
pp cccccccccc pp
pp ppp
ppppppppppppppppp
pp
pp
pp
pp
pp
pp
pp
pp
pp
First Printing, 1984
Copyright (C) New Mexico Tech 1984, 1985. All rights reserved.
The information in this manual is intended for internal use only
by New Mexico Tech (NMT). In no way should the information in
this manual be construed as a commitment by NMT. NMT assumes no
responsibility for any errors that may appear in this document.
UNIX is a trademark of Western Electric. DEC, DECSYSTEM-20,
TOPS-20, MACRO-20, RUNOFF, VAX, and VMS are trademarks of Digital
Equipment Corporation.
PREFACE
Document Objective
This document is intended as a basic reference for use of
the Version 7 C compiler at New Mexico Tech.
Intended Audience
This is not a tutorial on TOPS-20 or C. A working knowledge
of both TOPS-20 and the C language are assumed on the part
of the reader.
Other Documents
There is a user guide for the C standard library in
<HELP>CL-USER.DOC. Also, <HELP>CC-BUGS.DOC describes
currently-known bugs in the Version 7 C compiler. The C
--- -
Programming Language (Kernighan and Ritchie) is a standard
----------- --------
reference for the C language. A variety of documents cover
TOPS-20 and its use.
Conventions
This manual uses the following conventions:
"<RET>" represents a carriage return/line feed (ASCII
13/10 decimal).
"^" (circumflex) represents a control character. For
example, ^C represents pressing the keyboard "CONTROL"
or "CTRL" key and "C" key simultaneously. Depending on
the context, "^" can also mean the C language's
"exclusive or" operator.
Underlining indicates information that must be typed by
-----------
the user in examples, and is also used for titles of
publications.
CHAPTER 1
INTRODUCTION
This document describes New Mexico Tech's Version 7 C compiler
and library.
This C system is incompatible with the old version 6 system,
meaning that functions compiled with the old version cannot be
linked together with functions compiled with the new version and
vice-versa.
CHAPTER 2
USING THE COMPILER
This section of the document describes use of the compiler,
including command strings and switches.
2.1 WHERE TO FIND THE COMPILER
The version 7 C compiler and its auxiliary files reside in
the directory "PS:<SUBSYS>", along with the other compilers
on the system.
2.2 HOW TO RUN THE COMPILER
To invoke the compiler, type
@COMPILE file1, file2, .../LANGUAGE-SWITCHES:"/sw1/sw2..."
------- ------ ------ -----------------------------------
or
@LOAD file1, file2, .../LANGUAGE-SWITCHES:"/sw1/sw2..."
---- ------ ------ -----------------------------------
or
@CC
--
CC>file1/sw1/sw2...
----------------
CC>file2/sw1/sw2...
----------------
CC>...
---
USING THE COMPILER Page 2-2
2.3 ACTION SWITCHES
Action switches are switches that may be typed in place of a
file (i.e., as the first thing on the command line). The
action switches are used to cause things other than
compilation to take place.
The action switches are:
Switch Meaning
------ -------
/Exit Leave the compiler.
/Help Type this text on the terminal.
/List-default-settings List the default settings (see
/Set-default, below, and section
2.5).
/Quit Same as /Exit.
/Set-default:/dsw... Set default(s). Each /dsw is a
default switch, as documented in
section 2.5.
2.4 COMPILATION SWITCHES
The compilation switches are:
Switch Meaning
------ -------
/Binary: [file] Do a compilation (to relocatable
form). By default, the object
file is DSK:<sourcename>.REL; if
the optional "file" is given in
the switch, the object code is
written there instead.
/CAllstack-size: [size] (For main modules) set the size of
the function call stack (size must
be octal).
/COMMAnd-line-args (For main modules) cause emitted
program to look for command-line
arguments.
/COMMEnts-strip (When listing) remove comments
from the input source text.
/Cref Create an output file suitable as
input to the CREF program (for
now, this switch only causes a
listing).
/DAtastack-size: [size] (For main modules) set the size of
the data stack (size must be
octal).
/ERror-list: [file] Print error messages to the given
file, in addition to the terminal.
By default, the error listing is
sent to DSK:<sourcename>.ERR; if
USING THE COMPILER Page 2-3
the optional "file" is given in
the switch, the error listing is
sent there instead.
/Listing: [file] Do a listing. The listing is
generated in a separate pass over
the source file, after compilation
(if any) is done. By default, the
listing is sent to
DSK:<sourcename>.LST; if the
optional "file" is given in the
switch, the listing is sent there
instead.
/NOBinary Do not compile to relocatable
form.
/NOCOMMAnd-line-args (For main modules) cause emitted
program not to look for
command-line arguments.
/NOCOMMEnts-strip (When listing) do not remove
comments from the input source
text.
/NOCref Do not create an output file
suitable as input to the CREF
program.
/NOERror-list Do not print error messages other
than to the terminal.
/NOListing Do not do a listing.
/NONotes Do not print notice-level
messages.
/NOObject Same as "/NOBinary"
/NORECognize-pp-commands (When listing) cause the
preprocessor not to recognize the
'#' preprocessor commands.
/NOREQuest: [libname] Cause the emitted .REL file not to
contain a request for the given
library module.
/NOSymbol-dump (When compiling) do not do a dump
of the global symbols after
compilation is complete.
/NOTEs Print notice-level messages.
/NOTRaceable-code (When compiling) Do not emit code
which can be traced by the runtime
tracing routines (see section
3.7).
/NOWArnings Do not print warning-level
messages.
/NOWHitespace-strip (When listing) do not remove white
space from the input source text.
/Object: [file] Same as "/Binary:"
/RECognize-pp-commands (When listing) cause the
preprocessor to recognize the '#'
preprocessor commands.
/REQuest: [libname] Cause the emitted .REL file to
contain a request for the given
library module.
USING THE COMPILER Page 2-4
/Symbol-dump: [file] (When compiling) do a dump of the
global symbols after compilation
is complete. By default, the dump
is sent to DSK:<sourcename>.SYM;
if the optional "file" is given in
the switch, the dump is sent there
instead.
/Traceable-code (When compiling) Emit code which
can be traced by the runtime
tracing routines (see section
3.7).
/WArnings Print warning-level messages.
/Whitespace-strip (When listing) remove unnecessary
white space from the input source
text.
The default settings are:
/Binary: True, file is sourcename.REL
/CAllstack-size 010000
/COMMAnd-line-args True
/COMMEnts-strip False
/Cref False
/DAtastack-size 0100000
/Error-list: False
/Listing: False
/NOTEs False
/RECognize-pp-commands True
/REQuest CLIB
/Symbol-dump: False
/Traceable-code False
/WArnings True
/WHitespace-strip False
2.5 DEFAULT SWITCHES
The default switches can be given after the action switch
/Set-default; they are used to set default compilation
switch values that last until either the current invocation
of the compiler is ended or until other defaults supersede
them. For example, if one wanted to get listings with the
extension ".LIS" of several source files called A.C, B.C,
and C.C, but not actually compile those source files, one
could type:
@CC
--
CC>/set-default:/listing/ext-listing-file:lis/noobject
---------------------------------------------------
CC>a
-
USING THE COMPILER Page 2-5
CC>b
-
CC>c
-
CC>/exit
-----
The default switches are:
Switch Meaning
------ -------
/Binary Same as the corresponding
compilation switch, except that no
filename can be given here.
/CAllstack-size: [size] Same as the corresponding
compilation switch.
/COMMAnd-line-args Same as the corresponding
compilation switch.
/COMMEnts-strip Same as the corresponding
compilation switch.
/Cref Same as the corresponding
compilation switch.
/DAtastack-size: [size] Same as the corresponding
compilation switch.
/Default Make all settings be their default
values (i.e., the values they had
when the compiler was started;
see below).
/ERror-List Same as the corresponding
compilation switch, except that no
filename can be given here.
/EXT-Binary-file:XXX Make the default extension for
object files be ".XXX", instead of
".REL". If "XXX" is omitted, the
default extension will become
".REL". To set the default object
file extension explicitly to
nothing, use /noext-binary-file.
/EXT-Error-list-file:XXX Make the default extension for
error listing files be ".XXX",
instead of ".ERR". If "XXX" is
omitted, the default extension
will become ".ERR". To set the
default error listing file
extension explicitly to nothing,
use /noext-error-list-file.
/EXT-List-file:XXX Make the default extension for
list files be ".XXX", instead of
".LST". If "XXX" is omitted, the
default extension will become
".LST". To set the default list
file extension explicitly to
nothing, use /noext-list-file.
/EXT-Object-file:XXX Same as "/ext-binary-file:".
USING THE COMPILER Page 2-6
/EXT-Symbol-dump-file:XXX Make the default extension for
symbol table dump files be ".XXX",
instead of ".SYM". If "XXX" is
omitted, the default extension
will become ".SYM". To set the
default symbol dump file extension
explicitly to nothing, use
/noext-symbol-dump-file.
/Listing Same as the corresponding
compilation switch, except that no
filename can be given here.
/NOBinary Same as the corresponding
compilation switch.
/NOCOMMAnd-line-args Same as the corresponding
compilation switch.
/NOCOMMEnts-strip Same as the corresponding
compilation switch.
/NOCref Same as the corresponding
compilation switch.
/NOERror-list Same as the corresponding
compilation switch.
/NOEXT-Binary-file Make the default extension for
object files be nothing.
/NOEXT-Error-list-file Make the default extension for
error listing files be nothing.
/NOEXT-List-file Make the default extension for
list files be nothing.
/NOEXT-Object-file Same as "/noext-binary-file".
/NOEXT-Symbol-dump-file Make the default extension for
symbol table dump files be
nothing.
/NOListing Same as the corresponding
compilation switch.
/NONotes Same as the corresponding
compilation switch.
/NOObject Same as "/nobinary".
/NORecognize-pp-commands Same as the corresponding
compilation switch.
/NOREQuest: [libname] Same as the corresponding
compilation switch.
/NOSymbol-dump Same as the corresponding
compilation switch.
/NOTEs Same as the corresponding
compilation switch.
/NOTRaceable-code Same as the corresponding
compilation switch.
/NOWArnings Same as the corresponding
compilation switch.
/NOWHitespace-strip Same as the corresponding
compilation switch.
/Object Same as "/binary".
/Recognize-pp-commands Same as the corresponding
compilation switch.
/REQuest: [libname] Same as the corresponding
USING THE COMPILER Page 2-7
compilation switch.
/Symbol-dump Same as the corresponding
compilation switch, except that no
filename can be given here.
/Traceable-code Same as the corresponding
compilation switch.
/WArnings Same as the corresponding
compilation switch.
/WHitespace-strip Same as the corresponding
compilation switch.
The default settings are:
/Binary True
/CAllstack-size 010000
/COMMAnd-line-args True
/COMMEnts-strip False
/Cref False
/DAtastack-size 0100000
/ERror-List False
/EXT-List-file: LST
/EXT-Error-list-file: ERR
/EXT-Object-file: REL
/EXT-Symbol-dump-file: SYM
/Listing False
/NOTEs False
/RECognize-pp-commands True
/REQuest CLIB
/Symbol-dump False
/Traceable-code False
/WArnings True
/WHitespace-strip False
CHAPTER 3
PECULIARITIES OF THE TOPS-20 C IMPLEMENTATION
3.1 I/O REDIRECTION AND ARGC/ARGV
I/O redirection (by "<inputfile" and ">outputfile" on the
command line) is supported by this implementation. There
must be no white space between the "<" or ">" and the
filename, however. Argc and argv work like they do under
UNIX, with arguments separated by blanks (not commas, like
other TOPS-20 programs). ">&" redirection (redirection of
stderr in addition to stdout) is not supported.
3.2 SIGNIFICANCE OF NAMES
Within the compiler, names are significant to nine
characters, with uppercase and lowercase letters distinct.
However, since extern and static symbols are placed in the
generated .REL output, they are significant to only six
characters, with no distinction between uppercase and
lowercase letters. The "_" (underscore) character is
translated into a "." (period) in extern and static symbols.
3.3 SIZES OF DATA OBJECTS
Int, short, long, unsigned, float, double, and pointer
objects all occupy one 36-bit DEC-20 word. A character
requires seven bits of storage. A single char object
resides in the low-order seven bits of a 36-bit word. Char
arrays and strings are packed five seven-bit bytes per word,
left-justified with bit 35 unused.
Bit field structure members are packed into words, beginning
at the left end (sign bit, or bit 0).
The sizeof() operator returns the size of its argument in
seven-bit bytes. Thus, "sizeof(char)" is 1, "sizeof(int)"
is 5, and so on. For struct types, the size of each field
PECULIARITIES OF THE TOPS-20 C IMPLEMENTATION Page 3-2
is rounded up to the next word boundary. For structure
members which are bit fields, the size is rounded up to the
next byte (so if B1 is a bit field whose size is 13, and is
a member of the structure type of variable X, then
sizeof(X.B1) is 2).
3.4 COERCION ODDITIES
(Char *) of an int pointer produces a byte pointer that
points to the leftmost character that would have occupied
the word pointed to by the int pointer.
(Int *) of a char pointer produces a pointer that points to
the word in which the pointed-to char resides.
3.5 THE PREPROCESSOR
The compiler supports the standard C preprocessor, with the
following commands: #include (with both <> and ""),
#define, #undef, #ifdef, #ifndef, #else, and #endif. For
#include with <> the compiler prepends "SYS:" to the
filename; with "" it leaves the filename as is. This means
that you cannot put a device specifier on a filename in an
#include with <>, since that would result in the compiler's
trying to open a file with two device specifiers.
#If is also supported, with the restriction that the
expression must be either a constant (integer) or a
constant, a relational operator (==, !=, <, <=, >, >=), and
another (integral) constant.
3.6 THE STANDARD LIBRARY
A workable standard library is available, and is documented
in HLP:C-LIBRARY.DOC.
3.7 DEBUGGING SUPPORT
At the present time, there is no interactive debugger
available for C programs, although those familiar with MACRO
can use DDT with some effort. Intelligent use of debug
writes is probably the best bet for now. Debug output
should be done to stderr instead of stdout, since stdout is
buffered internally by the library functions and stderr is
not.
PECULIARITIES OF THE TOPS-20 C IMPLEMENTATION Page 3-3
The only other debugging aid is a facility for run-time
tracing of function entry and exit, via the compiler switch
"/traceable-code" and the library function _trace(). If
tracing is in use, each function call causes
"[enter x with arguments d (o) ...]" to be sent to a file,
and each "return()" causes "[exit x, returning d (o)]" to be
sent to a file, where "x" is the name of the function being
entered or left, and "d" and "o" are the decimal and octal
argument and return values for the given function. The
"enter"'s and "leave"'s are indented two spaces on each
entry, and deindented two spaces on each exit.
In addition, there are two other possibilities for the
"enter" message: "[enter x with no arguments]" means that
the function being entered was called with no arguments, and
"[enter x with unknown arguments]" means that the function
was called by some other function, which is in a module
which was not compiled with "/traceable-code".
To trace a program or part of a program, you must do two
things. First, you must give the "/traceable-code" compiler
switch for those source files containing functions whose
entries and exits you wish to have traced. Also, you must
call _trace() to start and stop the trace reporting.
_Trace() takes two arguments. The first is an int, which
has three possible values. A zero in this argument turns
off trace reporting and forgets about the indentation level.
Any positive value turns on reporting and causes the tracing
routines to begin keeping track of the indentation level,
while any negative value only causes them to begin keeping
track of the indentation. Additionally, any non-zero value
sets the indentation level to zero if the most recent call
to _trace() had a zero argument. The second argument to
_trace() is a file pointer for the file to which to write
the tracing information. Initially, the tracing routines
assume stderr as the target for the tracing information. If
you pass a file pointer other than NULL, the routines will
send the tracing information to that file instead. Passing
NULL for the second argument leaves the target file pointer
unchanged.
As an example, suppose you have the following C program:
PECULIARITIES OF THE TOPS-20 C IMPLEMENTATION Page 3-4
/*--------------------------------------------------*/
#include <stdio.h>
main()
{
fprintf(stderr, ">>>>> begin trace\n");
_trace(1, NULL);
funca(1);
_trace(0, NULL);
fprintf(stderr, ">>>>> end trace\n");
}
funca(a)
int a;
{
funcb(a + 1);
funcb(a + 2);
return(1);
}
funcb(b)
int b;
{
funcc(b + 1);
return(2);
}
funcc(c)
int c;
{
return(3);
}
/*--------------------------------------------------*/
If you compile this program with the "/traceable-code"
compiler switch and then load and execute it, the following
will appear on your terminal:
>>>>> begin trace
[enter funca with arguments 1 (01)]
[enter funcb with arguments 2 (02)]
[enter funcc with arguments 3 (03)]
[exit funcc, returning 3 (03)]
[exit funcb, returning 2 (02)]
[enter funcb with arguments 3 (03)]
[enter funcc with arguments 4 (04)]
[exit funcc, returning 3 (03)]
[exit funcb, returning 2 (02)]
[exit funca, returning 1 (01)]
>>>>> end trace
PECULIARITIES OF THE TOPS-20 C IMPLEMENTATION Page 3-5
3.8 RESTRICTIONS
The following are the current restrictions on the language
the compiler accepts.
3.9 BUGS
Please report apparent bugs, in either the compiler or the
standard library, to GREG via MAIL. At any given time, a
list of the known (both fixed and unfixed) bugs in the
compiler can be found in HLP:CC-BUGS.DOC. Note: the bugs
document has not been updated in a long time; in fact, it
is relatively useless right now, because the last time it
was updated, the compiler had a different parser.
CHAPTER 4
INTERFACING WITH MACRO CODE
4.1 FUNCTIONS AND ARGUMENTS
C programs run on two stacks: the call stack, and the data
stack. AC17 is the stack pointer for the call stack, which
holds only function return addresses. AC16 is the stack
pointer for the data stack, which holds auto variables and
function arguments.
The code generated by the compiler for a function call
evaluates the arguments right to left, pushing them onto the
stack as they are determined. Thus the first (leftmost)
argument is at 0(16), the second is at -1(16), and so on. A
PUSHJ is used to actually call the function, so the return
address is at 0(17).
The preceding data stack offsets are correct within the body
of the function only if it has no auto variables. The first
thing each function (including main()) does is to adjust the
data stack pointer upward to make room for its own auto
variables. Auto variables have stack offsets which are
increasing (less negative) in the order in which the
variables were declared in the source code. Thus, if one
has a function with three auto variables A, B, and C, then A
is at -2(16), B is at -1(16), and C is at 0(16). The
function's leftmost argument is at -3(16), the next argument
is at -4(16), and so on. The last thing the function does
before returning is to adjust that stack pointer back down,
removing the auto variables (but LEAVING the arguments; see
the next paragraph).
The calling routine adjusts the data stack pointer down to
remove the argument(s). This allows implementation of
functions with arbitrary numbers of arguments, and also
allows (proceed at your own risk) functions to be called
with the wrong number of arguments, without getting the
stack out of synch.
Function values are returned in AC0.
INTERFACING WITH MACRO CODE Page 4-2
The caller is responsible for saving any accumulators she
does not want destroyed. The callee may assume that all the
AC's (except AC17 and AC16, the stack pointers) are scratch.
4.2 INTERNAL REPRESENTATIONS OF DATA OBJECTS
Simple (scalar) objects take one word; a single char
variable contains the char in the rightmost 7 bits, with no
guarantees about the leftmost 29 bits (i.e., code which does
not know that it is working with a character variable could
set some of those leftmost 29 bits.
An array of non-char simple (scalar) objects is a contiguous
block of words.
An array of chars is a contiguous block of words containing
the chars packed left-to-right five per word, with bit 35 in
each word unused. A string is the same.
Structure members which are not bit fields are aligned to
word boundaries.
Bit field structure members are packed into words in the
order in which they are declared, starting at the left (bit
0, the sign bit). If some bit field member is declared with
a size greater than the amount of space left in the current
word, then that member begins at the leftmost bit of the
next word. Thus, given a structure type with three bit
field members of sizes 20, 7, and 13 bits respectively, the
first member would be in bits 0-19 of the structure's first
word, the second member would be in bits 20-26 of the first
word, and the third member would be in bits 0-12 of the
second word.
Non-char pointers are simply machine addresses (absolute,
without any indirection).
Char pointers are seven-bit-byte byte pointers which point
AT the character; note that monitor calls generally assume
that the pointer points immediately BEFORE the character.
In particular, if you use the _jsys() library routine and
have to pass pointers to strings to some JSYS, pass
(pointer - 1), so that the JSYS receives the ILDB/IDPB
pointer it expects.
CHAPTER 5
INTERFACING WITH FORTRAN CODE
5.1 OVERVIEW
Support is provided for C programs to call FORTRAN
subroutines and functions, but NOT the other way around.
This is the way the math library is implemented -- it uses
functions from FORLIB.
FORTRAN subroutines and functions are declared slightly
differently than C functions. If in place of the "extern"
storage class keyword in a declaration, you use the keyword
"fortran", then the objects made known by that declaration
are believed to be external FORTRAN subroutines and
functions (use the "void" type for subroutines).
When a FORTRAN subroutine or function is referenced
indirectly (e.g., when one calls a function whose address is
in a variable of type "pointer to function", and that
variable contains the address of a FORTRAN function), the
referencing code MUST KNOW that the object being referenced
is indeed a FORTRAN object. Since it is not possible to
tell the C compiler (by any legal C construct) that an
indirect reference is to a FORTRAN object, this sort of
thing is limited to use by MACRO code called by C code, in
which case the responsibility for building the argument
block and calling the indirectly-referenced object rests
with the programmer.
5.2 FUNCTIONS AND ARGUMENTS
We support the following types for FORTRAN functions and
FORTRAN parameters: "char", "int", "short", and "long"
(FORTRAN integer and logical), "float" and "double" (FORTRAN
real), "char *" and "char []" (FORTRAN char), and "(*)() /*
pointer to function */", (FORTRAN subroutine and function).
Parameters of type "unsigned", when passed to FORTRAN, are
passed as the FORTRAN argument type "octal". In addition,
you can pass arrays of or pointers to (which are the same
INTERFACING WITH FORTRAN CODE Page 5-2
thing) any of the above types except "(*)()".
All scalar parameters are pass-by-value; all arrays are
pass-by-reference. You can achieve the effect of a
pass-by-reference scalar by passing its address. Arrays
cannot be passed by value.
FORTRAN requires that the length of a character object
(which in C is a character constant, pointer, or array) be
known when that object is passed. Therefore, the C code
which sets up the argument entry for such a parameter to a
FORTRAN subroutine or function must compute the parameter's
length. For a character constant or character pointer, the
length is computed by counting characters (at run time, not
compile time) until a NUL is seen. For a character array,
the length is the declared length of the array. Thus, if
you pass a character pointer to FORTRAN, it MUST point at
something already, so that its length can be computed. This
requirement also holds if you are passing the address of a
character scalar variable in order to get the
pass-by-reference effect (in this case, the best thing to do
is to cast the address to be a character array of length
one). You can force any pointer-to-character object to be
of a specific length by casting it to be a character array
of that length.