Mini-Unix/usr/doc/c/ca

.pn 26
.fp 3 G
'tr ^\|
'hc $
'tr @
'll 6.5i
'ps 10
.ds op \s6\d\fIopt\fP\u\s10
.ds * \fR\v'.2'*\fP\v'-.2'
.ds ~ \v'.5'\s14~\s10\v'-.5'
'vs 11p
.de pg
.sp .4
.ti 1
..
.de et
.sp .2
.ft R
.ti 1
..
.de dp
.sp .7
.ne \\$1
.ft I
.nf
..
.de ed
.fi
.br
.ft R
..
.de ul
.sp 1.5
.ne 4
.ft G
..
.de ms
.sp  1
.ne 4
..
.de fo
'bp
..
.de he
.po 0
.tl '-'''
.po
'sp 0.5i
.ft I
.if o .tl '''C  Reference  Manual - %'
.if e .tl 'C  Reference  Manual - %'''
.ft
'sp 0.4i
..
.de bG
.br
.fp 3 G
.ft G
..
.de eG
.br
.ft R
..
.de it
.ft I
\\$1
.ft R
..
.de bd
.ft G
\\$1
.ft R
..
.de se
.br
.ft I
..
.wh 0 he
.wh -1i fo
.sp 2
.ce
REFERENCES
.sp 1.5
.ta 2
.tc @
.in 2
.ti 0
1.	Johnson, S. C., and Kernighan, B. W.
``The Programming Language B.'' Comp. Sci. Tech. Rep. #8., Bell Laboratories,
1972.
.sp .6
.ti 0
2.	Ritchie, D. M., and Thompson, K. L.
``The \s8UNIX\s10 Time-sharing System.''
C. ACM \fG7, \fR17, July, 1974, pp. 365-375.
.sp .6
.ti 0
3.	Peterson, T. G., and Lesk, M. E.
``A User's Guide to the C Language on the IBM 370.''
Internal Memorandum, Bell Laboratories, 1974.
.sp .6
.ti 0
4.	Thompson, K. L., and Ritchie, D. M.
.ft I
\s8UNIX\s10 Programmer's Manual.
.ft R
Bell Laboratories, 1973.
.sp .7
.ti 0
5.	Lesk, M. E., and Barres, B. A.
``The \s8GCOS\s10 C Library.''
Internal memorandum, Bell Laboratories,
1974.
.sp .7
.to 0
.ti 0
6.	Kernighan, B. W.  ``Programming in C\(mi A Tutorial.''
Unpublished internal memorandum,
Bell Laboratories, 1974.
.in 0
.bp
.sp 1.5
.ce 2
APPENDIX 1
.sp .3
Syntax Summary
.sp 1.5
.ta .5i 1i 1.5i 2i 2.5i
.in 3
1.  Expressions.
.sp 1
.dp 4
	expression:
		primary
		\**\fI expression
		\fG&\fI expression
		\fG\(mi\fI expression
		\fG!\fI expression
		\*~ expression
		\fR++\fI lvalue
		\fR\(mi\(mi\fI lvalue
		lvalue \fR++\fI
		lvalue \fR\(mi\(mi\fI
		\fGsizeof \fIexpression
		expression binop expression
		expression \fG?\fI expression \fG:\fI expression
		lvalue asgnop expression
		expression \fG,\fI expression
.ed
.dp 6
	primary:
		identifier
		constant
		string
		\fG( \fIexpression \fG)\fI
		\fIprimary \fG( \fIexpression-list\*(op \fG)\fI
		primary \fG[\fI expression \fG]\fI
		lvalue \fG. \fIidentifier
		primary \fG\(em> \fIidentifier
.ed
.dp 2
	lvalue:
		identifier
		primary \fG[ \fIexpression \fG]\fI
		lvalue \fG. \fIidentifier
		primary \fG\(em>\fI identifier
		\** \fI expression
		\fG(  \fIlvalue  \fG)\fR
.ed
.fi
.sp .7
The primary-expression operators
.dp
.ft G
	(^)  [^]  .  \(em>
.sp .5
.ed
have highest priority and group left-to-right.
The unary operators
.dp
.ft G
	\*  &  \(mi  !  \*~  \fR++  \(mi\(mi  \fGsizeof
.ed
.sp .5
have priority below the primary operators
but higher than any binary operator,
and group right-to-left.
Binary operators and the conditional operator
all group left-to-right, and have priority
decreasing
as indicated:
.dp
.ft I
	binop:
.ft G
		\**    /    %
		+    \(mi
		>>    <<
		<    >    <=    >=
		==    !=
		&
.tr ^^
		^
.tr ^\|
		\(or
		&&
		\(or\(or
		?  :
.tr ^^
.sp .4
.fi
.ft R
Assignment operators all have the same
priority, and all group right-to-left.
.dp 3
.ft I
	asgnop:
.ft G
		=  =+  =\(mi  =\**  =/  =%  =>>  =<<  =&  =^  =\(or
.ed
.tr ^\|
.sp .4
.ft R
The comma operator has the lowest priority, and groups left-to-right.
.sp .7
2.  Declarations.
.dp 2
	declaration:
		decl-specifiers declarator-list\*(op  \fG;
.ed
.dp 5
	decl-specifiers:
		type-specifier
		sc-specifier
		type-specifier sc-specifier
		sc-specifier type-specifier
.ed
.dp 4
	sc-specifier:
.ft G
		auto
		static
		extern
		register
.ed
.dp 6
	type-specifier:
		\fGint
		\fGchar
		\fGfloat
		\fGdouble
		struct { \fItype-decl-list }\fG
		struct \fIidentifier { type-decl-list }\fG
		struct \fIidentifier\fG
.ed
.dp 2
	declarator-list:
		declarator
		declarator \fG,\fI declarator-list
.ed
.dp 6
	declarator:
		identifier
		\** \fIdeclarator
		declarator \fG( )\fI
		declarator \fG[\fI constant-expression\*(op \fG]\fI
		\fG( \fIdeclarator \fG)
.ed
.dp 2
	type-decl-list:
		type-declaration
		type-declaration type-decl-list
.ed
.dp 2
	type-declaration:
		type-specifier declarator-list  \fG;
.ed
.sp 1.5
3. Statements.
.dp 1
	statement:
		expression \fG;
.se
		{ \fIstatement-list }
.se
		\fGif ( \fIexpression \fG) \fIstatement
.se
		\fGif ( \fI expression \fG) \fIstatement \fGelse \fIstatement
.se
		\fGwhile ( \fIexpression \fG) \fIstatement
.se
		\fGfor ( \fIexpression\*(op \fG; \fIexpression\*(op \fG; \fIexpression\*(op \fG) statement
.se
		\fGswitch ( \fIexpression \fG) \fIstatement
.se
		\fGcase \fIconstant-expression \fG:\fI statement
.se
		\fGdefault : \fIstatement
.se
		\fGbreak ;
.se
		\fGcontinue ;
.se
.ft G
		return ;
.se
.ft G
		return ( \fIexpression \fG) ;
.se
.ft G
		goto \fIexpression \fG;
.se
		\fIidentifier \fG: \fIstatement
.se
		\fG;
.ed
.dp 2
	statement-list:
		statement
		statement statement-list
.sp 1.5
.ft R
4.  External definitions.
.dp 2
	program:
		external-definition
		external-definition program
.dp 2
	external-definition:
		function-definition
		data-definition
.ed
.dp 2
	function-definition:
		type-specifier\*(op \fIfunction-declarator function-body
.ed
.dp 2
	function-declarator:
		declarator \fG( \fI parameter-list\*(op \fG)
.ed
.dp 1
	parameter-list:
		identifier
		identifier \fG,\fI parameter-list
.ed
.dp 1
	function-body:
		type-decl-list function-statement
.ed
.dp 2
	function-statement:
		{ declaration-list\*(op statement-list }
.ed
.dp 2
	data-definition:
		\fGextern\fI\*(op type-specifier\*(op init-declarator-list\*(op \fG;
.ed
.dp 2
	init-declarator-list:
		init-declarator
		init-declarator \fG,\fI init-declarator-list
.ed
.dp 2
	init-declarator:
		declarator initializer\*(op
.ed
.dp 5
	initializer:
		constant
		{ constant-expression-list }
.ed
.dp 5
	constant-expression-list:
		constant-expression
		constant-expression \fG,\fI constant-expression-list
.ed
.dp 2
	constant-expression:
		expression
.ed
.sp .4
5.  Preprocessor
.dp 1
	\fG# define \fIidentifier token-string
.ed
.dp 1
	\fG# include "\fIfilename^\fG"
.ed
.in 0
.bp
.ds s \\s8
.ds n \\s10
.ft R
.fi
.sp 1
.ce 2
APPENDIX 2
Implementation Peculiarities
.sp 2
This Appendix briefly summarizes the differences between the implementations
of C on the \*sPDP\*n-11 under \*sUNIX\*n and on the
\*sHIS\*n 6070 under \*sGCOS\*n;
it includes some known bugs
in each implementation.
Each entry is keyed by an indicator as follows:
.sp
.ta .4i .8i
.nf
	h	hard to fix
	g	\*sGCOS\*n version should probably be changed
	u	\*sUNIX\*n version should probably be changed
	d	Inherent difference likely to remain
.sp
.fi
This list was prepared by M. E. Lesk, S. C. Johnson,
E. N. Pinson, and the author.
.sp 2
.fi
.ta .4i 1.2i
.in 1.2i
.ti0
.ft I
A. Bugs or differences from C language specifications
.ft R
.sp
.ti0
hg	A.1)	\*sGCOS\*n does not do type conversions in ``?:''.
.ti0
hg	A.2)	\*sGCOS\*n has a bug in \fGint\fR and \fGreal\fR comparisons; the numbers
are compared by subtraction, and the difference must not overflow.
.ti 0
g	A.3)	When \fIx\fR is a \fGfloat\fR, the construction ``test ? \(mix : x''
is illegal on \*sGCOS\*n.
.ti0
hg	A.4)	``p1\(mi>p2 =+ 2'' causes a compiler error, where p1 and p2 are pointers.
.ti0
u	A.5)	On \*sUNIX\*n, the expression in a \fGreturn\fR statement is \fInot\fR
converted to the type of the function, as promised.
.ti0
hug	A.6)	\fGentry\fR statement is not implemented at all.
.sp
.ne 5
.ft I
.ti0
.ft I
B. Implementation differences
.ft R
.sp
.ti0
d	B.1)	Sizes of character constants differ; \*sUNIX\*n: 2, \*sGCOS\*n: 4.
.ti0
d	B.2)	Table sizes in compilers differ.
.ti0
d	B.3)	\fGchar\fRs and \fGint\fRs have different sizes;
\fGchar\fRs are 8 bits on \*sUNIX\*n, 9 on \*sGCOS\*n; words are 16 bits
on \*sUNIX\*n and 36 on \*sGCOS\*n.
There are corresponding differences in representations of
\fGfloat\fRs and \fGdouble\fRs.
.ti0
d	B.4)	Character arrays stored left to right in a word
in \*sGCOS\*n, right to left in \*sUNIX\*n.
.ti0
g	B.5)	Passing of floats and doubles differs;
\*sUNIX\*n passes on stack, \*sGCOS\*n passes pointer (hidden to normal user).
.ti0
g	B.6)	Structures and strings are aligned on a word
boundary in \*sUNIX\*n, not aligned in \*sGCOS\*n.
.ti0
g	B.7)	\*sGCOS\*n preprocessor supports #rename, #escape;
\*sUNIX\*n has only #define, #include.
.ti0
u	B.8)	Preprocessor is not invoked on \*sUNIX\*n unless first
character of file is ``#''.
.ti0
u	B.9)	The external definition ``static int .^.^.''
is legal on \*sGCOS\*n, but gets a diagnostic on \*sUNIX\*n.
(On \*sGCOS\*n it means an identifier global to the
routines in the file but invisible to routines
compiled separately.)
.ti 0
g	B.10)	A compound statement on \*sGCOS\*n must contain one ``;''
but on \*sUNIX\*n may be empty.
.ti 0
g	B.11)	On \*sGCOS\*n case distinctions in identifiers and keywords are
ignored; on \*sUNIX\*n case is significant everywhere,
with keywords in lower case.
.sp
.ne 5
.ti0
.ft I
C. Syntax Differences
.ft R
.sp
.ti0
g	C.1)	\*sUNIX\*n allows broader classes of initialization;
on \*sGCOS\*n an initializer must be a constant, name, or string.
Similarly,
\*sGCOS\*n is much stickier about wanting braces
around initializers and in particular they must be present
for array initialization.
.ti0
g	C.2)	``int extern'' illegal on \*sGCOS\*n; must have ``extern int''
(storage class before type).
.ti0
g	C.3)	Externals on \*sGCOS\*n must have a type (not defaulted
to \fGint\fR).
.ti0
u	C.4)	\*sGCOS\*n allows initialization of internal \fGstatic\fR
(same syntax as for external definitions).
.ti0
g	C.5)	integer\(mi>... is not allowed on \*sGCOS\*n.
.ti0
g	C.6)	Some operators on pointers are illegal on \*sGCOS\*n (<, >).
.ti0
g	C.7)	\fGregister\fR storage class means something on \*sUNIX\*n,
but is not accepted on \*sGCOS\*n.
.ti0
g	C.8)	Scope holes: ``int x; f^(^^)^{int x;}'' is illegal on
\*sUNIX\*n but defines two variables on \*sGCOS\*n.
.ti0
g	C.9)	When function names are used as arguments on \*sUNIX\*n,
either ``fname'' or ``&fname'' may be used to get a pointer to the function;
on \*sGCOS\*n ``&fname'' generates a doubly-indirect pointer.
(Note that both are wrong since the ``&''
is supposed to be supplied for free.)
.sp
.ne 5
.ti0
.ft I
D. Operating System Dependencies
.sp
.ft R
.ti0
d	D.1)	\*sGCOS\*n allocates external scalars by SYMREF;
\*sUNIX\*n allocates external scalars as labelled common;
as a result there may be many
uninitialized external definitions of the same variable
on \*sUNIX\*n but only one on \*sGCOS\*n.
.ti0
d	D.2)	External names differ in allowable length and
character set;
on \*sUNIX\*n, 7 characters and both cases; on \*sGCOS\*n
6 characters and only one case.
.sp
.ne 5
.ft I
.ti0
E. Semantic Differences
.ft R
.sp
.ti0
hg	E.1)	``int i, *p; p=i; i=p;'' does nothing on \*sUNIX\*n,
does something on \*sGCOS\*n (destroys right half of i) .
.ti0
d	E.2)	``>>'' means arithmetic shift on \*sUNIX\*n, logical on \*sGCOS\*n.
.ti0
d	E.3)	When a \fGchar\fR is converted to integer, the result is always
positive on \*sGCOS\*n but can be negative on \*sUNIX\*n.
.ti0
d	E.4)	Arguments of subroutines are evaluated left-to-right
on \*sGCOS\*n, right-to-left on \*sUNIX\*n.