add directory Ref-docs
This commit is contained in:
810
Ref-docs/C/types.html
Normal file
810
Ref-docs/C/types.html
Normal file
@@ -0,0 +1,810 @@
|
||||
<HTML><HEAD><TITLE>Types</TITLE></HEAD><BODY BGCOLOR="#FFFFFF">
|
||||
|
||||
<H1><A NAME="Types">Types</A></H1><HR>
|
||||
|
||||
<P><B>
|
||||
<A HREF="#Type Classification">Type Classification</A>
|
||||
· <A HREF="#Arithmetic Types">Arithmetic Types</A>
|
||||
· <A HREF="#Basic Integer Types">Basic Integer Types</A>
|
||||
· <A HREF="#Bitfields">Bitfields</A>
|
||||
· <A HREF="#Enumerations">Enumerations</A>
|
||||
· <A HREF="#Floating-Point Types">Floating-Point Types</A>
|
||||
· <A HREF="#Deriving Types">Deriving Types</A>
|
||||
· <A HREF="#Pointer Types">Pointer Types</A>
|
||||
· <A HREF="#Structure Types">Structure Types</A>
|
||||
· <A HREF="#Union Types">Union Types</A>
|
||||
· <A HREF="#Array Types">Array Types</A>
|
||||
· <A HREF="#Function Types">Function Types</A>
|
||||
· <A HREF="#Incomplete Types">Incomplete Types</A>
|
||||
· <A HREF="#Type Qualifiers">Type Qualifiers</A>
|
||||
· <A HREF="#Compatible and Composite Types">Compatible and Composite Types</A>
|
||||
</B></P>
|
||||
<HR>
|
||||
|
||||
<P><B>Type</B> is a fundamental concept in Standard C. When you
|
||||
declare a name, you give it a type. Each expression and subexpression
|
||||
that you write has a type. This chapter shows each type you can write
|
||||
and how to classify it as either a
|
||||
<A HREF="#function types">function type</A>, an
|
||||
<A HREF="#object types">object type</A>, or an
|
||||
<A HREF="#incomplete types">incomplete type</A>.
|
||||
You see how an implementation can represent
|
||||
<A HREF="#Arithmetic Types">arithmetic types</A>
|
||||
and how to derive more complex
|
||||
<A HREF="#Pointer Types">pointer types</A>
|
||||
as well as others that are not
|
||||
<A HREF="#scalar types">scalar types</A>. You learn how to use
|
||||
<A HREF="#Type Qualifiers">type qualifiers</A> to specify access limitations
|
||||
for objects. This document also describes rules for forming a
|
||||
<A HREF="#Compatible and Composite Types">composite type</A> from two
|
||||
<A HREF="#Compatible and Composite Types">compatible types</A>.</P>
|
||||
|
||||
<H2><A NAME="Type Classification">Type Classification</A></H2>
|
||||
|
||||
<P>Types have a number of classifications:</P>
|
||||
|
||||
<P><IMG SRC="type_cl.gif" tppabs="http://ccs.ucsd.edu/c/gif/type_cl.gif"></P>
|
||||
|
||||
<P>The diagram shows you, for example,
|
||||
that the type <I>short</I> is an integer type, an arithmetic type, a
|
||||
<B><A NAME="scalar types">scalar type</A></B>, and an object type.
|
||||
Similarly, a <I>pointer to function</I>
|
||||
is a pointer type, a scalar type, and an object type.</P>
|
||||
|
||||
<P>A type can be in any of three major classes:</P>
|
||||
|
||||
<UL>
|
||||
<LI>A <B><A NAME="function types">function type</A></B>
|
||||
determines what type of result a function returns, and possibly what
|
||||
argument types it accepts when you call it.</LI>
|
||||
|
||||
<LI>An <B><A NAME="object types">object type</A></B> determines
|
||||
how an object is represented, what values it can express, and what
|
||||
operations you can perform on its values.</LI>
|
||||
|
||||
<LI>An <B><A NAME="incomplete types">incomplete type</A></B> determines
|
||||
whether you can complete the type and with what object types the type
|
||||
is compatible.</LI>
|
||||
</UL>
|
||||
|
||||
<P>Object types have a number of subclassifications. This document
|
||||
uses these subclassifications to simplify a number of descriptions.
|
||||
For example, you can declare a member of a structure to have any
|
||||
<A HREF="#object types">object type</A>,
|
||||
you can compare against zero any value that has
|
||||
<A HREF="#scalar types">scalar type</A>,
|
||||
you can multiply any two values that have
|
||||
<A HREF="#Arithmetic Types">arithmetic types</A>, and you
|
||||
can form the inclusive OR of any two values that have
|
||||
<A HREF="#integer types">integer types</A>.</P>
|
||||
|
||||
<H2><A NAME="Arithmetic Types">Arithmetic Types</A></H2>
|
||||
|
||||
<P>The <B>arithmetic types</B> describe objects that represent numeric
|
||||
values. You use
|
||||
<B><A NAME="integer types">integer types</A></B>
|
||||
to represent whole numbers, including zero or negative values.
|
||||
The three subclassifications of integer types are:</P>
|
||||
|
||||
<UL>
|
||||
<LI>the predefined
|
||||
<B><A HREF="#Basic Integer Types">basic integer types</A></B>
|
||||
|
||||
<LI>the <B><A HREF="#Bitfields">bitfield types</A></B>
|
||||
|
||||
<LI>the <B><A HREF="#Enumerations">enumeration types</A></B>
|
||||
</UL>
|
||||
|
||||
<P>You use
|
||||
<B><A NAME="floating-point types">floating-point types</A></B>
|
||||
to represent signed numbers that can have a fractional part.
|
||||
The range of values that you can
|
||||
represent with floating-point types is always much larger than the range
|
||||
you can represent with integer types, but the precision of floating-point
|
||||
values is limited. The translator predefines three floating-point
|
||||
types:</P>
|
||||
|
||||
<UL>
|
||||
<LI><I><A HREF="#float type">float</A></I></LI>
|
||||
|
||||
<LI><I><A HREF="#double type">double</A></I></LI>
|
||||
|
||||
<LI><I><A HREF="#long double type">long double</A></I></LI>
|
||||
</UL>
|
||||
|
||||
<H3><A NAME="Basic Integer Types">Basic Integer Types</A></H3>
|
||||
|
||||
<P>The translator predefines nine <B>basic integer types</B>. You can
|
||||
designate some of these types in more than one way. For a designation
|
||||
that has more than one type specifier, you can write the type specifiers
|
||||
in any order. For example, you can write the designation <CODE>unsigned
|
||||
short int</CODE> as any of:</P>
|
||||
|
||||
<PRE>
|
||||
unsigned short int unsigned int short
|
||||
short unsigned int short int unsigned
|
||||
int unsigned short int short unsigned</PRE>
|
||||
|
||||
<P>The following table lists the properties
|
||||
of all basic integer types:</P>
|
||||
|
||||
<PRE>
|
||||
<B>Alternate Minimum Restrictions on
|
||||
Designations Range Representation</B>
|
||||
|
||||
<B><A NAME="char type">char</A></B> [0, 128) same as either <I>signed char</I>
|
||||
or <I>unsigned char</I>
|
||||
|
||||
<B><A NAME="signed char type">signed char</A></B> (-128, 128) at least an 8-bit signed integer
|
||||
|
||||
<B><A NAME="unsigned char type">unsigned char</A></B> [0, 256) same size as <I>signed char</I>;
|
||||
no negative values
|
||||
|
||||
<B><A NAME="short type">short</A></B> (-2^15, 2^15) at least a 16-bit signed integer;
|
||||
signed short at least as large as <I>char</I>
|
||||
short int
|
||||
signed short int
|
||||
|
||||
<B><A NAME="unsigned short type">unsigned short</A></B> [0, 2^16) same size as <I>short</I>;
|
||||
unsigned short int no negative values
|
||||
|
||||
<B><A NAME="int type">int</A></B> (-2^15, 2^15) at least a 16-bit signed integer;
|
||||
signed at least as large as <I>short</I>
|
||||
signed int
|
||||
<B>none</B>
|
||||
|
||||
<B><A NAME="unsigned int type">unsigned int</A></B> [0, 2^16) same size as <I>int</I>;
|
||||
unsigned no negative values
|
||||
|
||||
<B><A NAME="long type">long</A></B> (-2^31, 2^31) at least a 32-bit signed integer;
|
||||
signed long at least as large as <I>int</I>
|
||||
long int
|
||||
signed long int
|
||||
|
||||
<B><A NAME="unsigned long type">unsigned long</A></B> [0, 2^32) same size as <I>long</I>;
|
||||
unsigned long int no negative values</PRE>
|
||||
|
||||
<P>If you write no type specifiers in a declaration, the type you
|
||||
specify is <I>int.</I> For example, the following declarations both
|
||||
declare <CODE>x</CODE> to have type <I>int:</I></P>
|
||||
|
||||
<PRE>
|
||||
extern int x;
|
||||
extern x;</PRE>
|
||||
|
||||
<P>This document refers to each predefined type by its first designation
|
||||
listed in the table, but written in italics. For example, <I>unsigned
|
||||
short</I> refers to the type you designate as <CODE>unsigned short</CODE>
|
||||
or as <CODE>unsigned short int</CODE>.</P>
|
||||
|
||||
<P>In this table, and in the tables that follow in this document,
|
||||
each minimum range is written as one or more ranges of values.
|
||||
The leftmost value is the lowest value in
|
||||
the range, and the rightmost is the highest. A left or right bracket
|
||||
indicates that the endpoint is included in the range. A left or right
|
||||
parenthesis indicates that the endpoint is <I>not</I> included in
|
||||
the range. Thus, the notation [0, 256) describes a range that includes
|
||||
0 through 255.</P>
|
||||
|
||||
<P>The following table lists the
|
||||
<B><A NAME="powers of 2">powers of 2</A></B> used
|
||||
in the other tables in this document. An implementation can represent
|
||||
a broader range of values than shown here, but not a narrower range:</P>
|
||||
|
||||
<PRE>
|
||||
<B>Power of 2 Decimal Value</B>>
|
||||
|
||||
2^15 32,768
|
||||
2^16 65,536
|
||||
2^31 2,147,483,648
|
||||
2^32 4,294,967,296</PRE>
|
||||
|
||||
<H3><A NAME="Bitfields">Bitfields</A></H3>
|
||||
|
||||
<P>A <B>bitfield</B> is an integer that occupies a specific number of
|
||||
contiguous bits within an object that has an integer type. You can
|
||||
declare bitfields based on any of three different sets of integer
|
||||
type designations to designate three different kinds of bitfields:</P>
|
||||
|
||||
<UL>
|
||||
<LI><B>plain bitfields</B>, whose signedness is
|
||||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||||
defined</A></LI>
|
||||
|
||||
<LI><B>signed bitfields</B></LI>
|
||||
|
||||
<LI><B>unsigned bitfields</B></LI>
|
||||
</UL>
|
||||
|
||||
<P>You declare bitfields only as members of a structure or a union.
|
||||
The expression you write after the colon specifies the size of the
|
||||
bitfield in bits. You cannot portably specify more bits than are used
|
||||
to represent type <I>int.</I></P>
|
||||
|
||||
<P>How the translator packs successive bitfield
|
||||
<A HREF="declare.html#Member Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Member Declaration">declarations</A> into
|
||||
integer type objects is
|
||||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||||
defined</A>.</P>
|
||||
|
||||
<P>The following table lists the properties of
|
||||
various kinds of bitfields:</P>
|
||||
|
||||
<PRE>
|
||||
<B>Alternate Minimum Restrictions on
|
||||
Designations Range Representation</B>
|
||||
|
||||
int [0, 2^(N-1)) same as either <I>signed bitfields</I>
|
||||
<B>none</B> or <I>unsigned bitfields</I>
|
||||
|
||||
signed (-2^(N-1), 2^(N-1)) N-bit signed integer;
|
||||
signed int size not larger than <I>int</I>
|
||||
|
||||
unsigned [0, 2^N) N-bit unsigned integer;
|
||||
unsigned int size not larger than <I>int</I></PRE>
|
||||
|
||||
<P>For example, you can declare the flags
|
||||
register of some Intel 80X86 processors as:</P>
|
||||
|
||||
<PRE>
|
||||
struct flags {
|
||||
unsigned int
|
||||
cf:1, :1, pf:1, :1,
|
||||
af:1, :1, zf:1, sf:1,
|
||||
tf:1, if:1, df:1, of:1,
|
||||
iopl:2, nt:1, :1;
|
||||
};</PRE>
|
||||
|
||||
<P>assuming that the translator packs bitfields from least significant
|
||||
bit to most significant bit within a 16-bit object.</P>
|
||||
|
||||
<H3><A NAME="Enumerations">Enumerations</A></H3>
|
||||
|
||||
<P>You declare an <B>enumeration</B> with one or more
|
||||
<B><A NAME="enumeration constants">enumeration constants</A></B>.
|
||||
For example:</P>
|
||||
|
||||
<PRE>
|
||||
enum Hue {black, red, green, blue = 4, magenta};</PRE>
|
||||
|
||||
<P>This declaration defines an enumeration type (with tag <CODE>Hue</CODE>)
|
||||
that has the enumeration constants
|
||||
<CODE>black</CODE> (with value 0), <CODE>red</CODE>
|
||||
(with value 1), <CODE>green</CODE> (with value 2),
|
||||
<CODE>blue</CODE> (with value 4),
|
||||
and <CODE>magenta</CODE> (with value 5).</P>
|
||||
|
||||
<P>An enumeration is compatible with the type that the translator
|
||||
chooses to represent it, but the choice is
|
||||
<A HREF="portable.html#implementation defined" tppabs="http://ccs.ucsd.edu/c/portable.html#implementation defined">implementation
|
||||
defined</A>.
|
||||
The translator can represent an enumeration as any integer type that
|
||||
promotes to <I>int.</I> A value you specify for an enumeration constant
|
||||
(such as <CODE>4</CODE> for <CODE>blue</CODE> above) must be an
|
||||
<A HREF="express.html#arithmetic constant expression" tppabs="http://ccs.ucsd.edu/c/express.html#arithmetic constant expression">arithmetic
|
||||
constant expression</A> and representable
|
||||
as type <I>int.</I> If you write:</P>
|
||||
|
||||
<PRE>
|
||||
enum Hue {red, green, blue = 4} x;
|
||||
int *p = &x; <B>DANGEROUS PRACTICE</B></PRE>
|
||||
|
||||
<P>not all translators treat <CODE>&x</CODE>
|
||||
as type <I>pointer to int.</I></P>
|
||||
|
||||
<H3><A NAME="Floating-Point Types">Floating-Point Types</A></H3>
|
||||
|
||||
<P>The translator predefines three <B>floating-point types</B>. All represent
|
||||
values that are signed approximations to real values, to some minimum
|
||||
specified precision, over some minimum specified range.
|
||||
The following table lists the properties of
|
||||
the three floating-point types:</P>
|
||||
|
||||
<PRE>
|
||||
<B> Minimum Restrictions on
|
||||
Designation Range Representation</B>
|
||||
|
||||
<B><A NAME="float type">float</A></B> [-10^+38, -10^-38] at least 6 decimal digits
|
||||
0 of precision
|
||||
[10^-38, 10^+38]
|
||||
|
||||
<B><A NAME="double type">double</A></B> [-10^+38, -10^-38] at least 10 decimal digits;
|
||||
0 range and precision
|
||||
[10^-38, 10^+38] at least that of <I>float</I>
|
||||
|
||||
<B><A NAME="long double type">long double</A></B> [-10^+38, -10^-38] at least 10 decimal digits;
|
||||
0 range and precision
|
||||
[10^-38, 10^+38] at least that of <I>double</I></PRE>
|
||||
|
||||
<P>No relationship exists between the representations of
|
||||
<A HREF="#integer types">integer types</A> and floating-point types.</P>
|
||||
|
||||
<H2><A NAME="Deriving Types">Deriving Types</A></H2>
|
||||
|
||||
<P>You can <B>derive</B> types from other types by declaring:</P>
|
||||
|
||||
<UL>
|
||||
<LI><B><A HREF="#Pointer Types">pointers</A></B> to other types</LI>
|
||||
|
||||
<LI><B><A HREF="#Structure Types">structures</A></B>
|
||||
containing other object types</LI>
|
||||
|
||||
<LI><B><A HREF="#Union Types">unions</A></B>
|
||||
containing other object types</LI>
|
||||
|
||||
<LI><B><A HREF="#Array Types">arrays</A></B> of other object types</LI>
|
||||
|
||||
<LI><B><A HREF="#Function Types">functions</A></B>
|
||||
that return object or incomplete types</LI>
|
||||
</UL>
|
||||
|
||||
<P>You cannot call a function that returns an incomplete type other
|
||||
than <I>void.</I> Any other incomplete return type must be complete
|
||||
before you call the function.</P>
|
||||
|
||||
<P>The following table summarizes the constraints
|
||||
on deriving types:</P>
|
||||
|
||||
<PRE>
|
||||
<B>Derived Function Object Incomplete
|
||||
Type Type Type Type</B>
|
||||
|
||||
pointer to any any except any
|
||||
bitfield types
|
||||
|
||||
structure --- any ---
|
||||
containing
|
||||
|
||||
union --- any ---
|
||||
containing
|
||||
|
||||
array of --- any except ---
|
||||
bitfield types
|
||||
|
||||
function --- any except any except
|
||||
returning bitfield types incomplete
|
||||
or array types array types</PRE>
|
||||
|
||||
<H3><A NAME="Pointer Types">Pointer Types</A></H3>
|
||||
|
||||
<P>A <B>pointer type</B> describes an object whose values are the
|
||||
storage addresses that the program uses to designate functions or
|
||||
objects of a given type. You can declare a pointer type that points
|
||||
to any other type except a bitfield type. For example:</P>
|
||||
|
||||
<PRE>
|
||||
char *pc; <B>pc is a pointer to char</B>
|
||||
void *pv; <B>pv is a pointer to void</B>
|
||||
void (*pf)(void); <B>pf is a pointer to a function</B></PRE>
|
||||
|
||||
<P>Several constraints exist on the representation of pointer types:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Every pointer type can represent a
|
||||
<B><A NAME="null pointer value">null pointer value</A></B>
|
||||
that compares equal to an integer zero, and does not equal the address
|
||||
of <I>any</I> function or object in the program.</LI>
|
||||
|
||||
<LI>The types <I>pointer to char, pointer to signed char, pointer
|
||||
to unsigned char,</I> and <I>pointer to void</I>
|
||||
share the same representation.</LI>
|
||||
|
||||
<LI>Any valid object pointer can safely be converted to
|
||||
<I>pointer to void</I> and back to the original type.</LI>
|
||||
|
||||
<LI>All <I>pointer to function</I> types share the same representation
|
||||
(which need not be the same as for <I>pointer to void</I>).</LI>
|
||||
|
||||
<LI>Otherwise, different pointer types can have
|
||||
different representations.</LI>
|
||||
</UL>
|
||||
|
||||
<P>No relationship exists between the representations of pointer
|
||||
types and
|
||||
<A HREF="#integer types">integer</A> or
|
||||
<A HREF="#floating-point types">floating-point types</A>.</P>
|
||||
|
||||
<H3><A NAME="Structure Types">Structure Types</A></H3>
|
||||
|
||||
<P>A <B>structure type</B> describes an object whose values are
|
||||
composed of <I>sequences</I> of
|
||||
<A HREF="declare.html#Member Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Member Declaration">members</A>
|
||||
that have other object types. For example:</P>
|
||||
|
||||
<PRE>
|
||||
struct {
|
||||
char ch; <B>struct contains a char</B>
|
||||
long lo; <B>followed by a long</B>
|
||||
} st; <B>st contains st.ch and st.lo</B></PRE>
|
||||
|
||||
<P>The members occupy successive locations in storage, so an object
|
||||
of structure type can represent the value of all its members at the
|
||||
same time. Every structure member list (enclosed in braces) within
|
||||
a given translation unit defines a different
|
||||
(<A HREF="#Compatible and Composite Types">incompatible</A>)
|
||||
structure type.</P>
|
||||
|
||||
<P>Some implementations align objects of certain types on special
|
||||
storage boundaries. A Motorola 680X0, for example, requires that a
|
||||
<I>long</I> object be aligned on an even storage boundary. (The byte
|
||||
with the lowest address, used to designate the entire object, has
|
||||
an address that is a multiple of 2.)</P>
|
||||
|
||||
<P>A structure type can contain a
|
||||
<B><A NAME="holes">hole</A></B> after each member
|
||||
to ensure that the member following is suitably aligned. A hole can
|
||||
occur after the last member of the structure type to ensure that an
|
||||
array of that structure type has each element of the array suitably
|
||||
aligned. In the Motorola 68000 example above, a one-byte (or larger)
|
||||
hole occurs after the member <CODE>ch</CODE>, but a hole probably does not
|
||||
occur after the member <CODE>lo</CODE>.
|
||||
Holes do not participate in representing
|
||||
the value of a structure.</P>
|
||||
|
||||
<H3><A NAME="Union Types">Union Types</A></H3>
|
||||
|
||||
<P>A <B>union type</B> describes an object whose values are composed
|
||||
of <I>alternations</I> of
|
||||
<A HREF="declare.html#Member Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Member Declaration">members</A>
|
||||
that have other object types. For example:</P>
|
||||
|
||||
<PRE>
|
||||
union {
|
||||
char ch; <B>union contains a char</B>
|
||||
long lo; <B>followed by a long</B>
|
||||
} un; <B>un contains un.ch or un.lo</B></PRE>
|
||||
|
||||
<P>All members of a union type overlap in storage, so an object
|
||||
of union type can represent the value of only one of its members at
|
||||
any given time. Every union member list (enclosed in braces) within
|
||||
a translation unit defines a different
|
||||
(<A HREF="#Compatible and Composite Types">incompatible</A>)
|
||||
union type.</P>
|
||||
|
||||
<P>Like a structure type, a union type can have a
|
||||
<A HREF="#holes">hole</A> after each
|
||||
of its members. The holes are at least big enough to ensure that a
|
||||
union type occupies the same number of bytes (regardless of which
|
||||
member is currently valid) and to ensure that an array of that union
|
||||
type has each element of the array suitably aligned.</P>
|
||||
|
||||
<H3><A NAME="Array Types">Array Types</A></H3>
|
||||
|
||||
<P>An <B>array type</B> describes an object whose values are composed
|
||||
of <I>repetitions</I> of <I>elements</I> that have some other object
|
||||
type. For example:</P>
|
||||
|
||||
<PRE>
|
||||
char ac[10]; <B>contains chars ac[0], ac[1], etc.</B></PRE>
|
||||
|
||||
<P>Elements of an array type occupy successive storage locations,
|
||||
beginning with element number zero, so an object of array type can represent
|
||||
multiple element values at the same time.</P>
|
||||
|
||||
<P>The number of elements in an array type is specified by its
|
||||
<B><A NAME="#repetition count">repetition count</A></B>.
|
||||
In the example above, the repetition count is 10.
|
||||
An array type does not contain additional
|
||||
<A HREF="#holes">holes</A> because all
|
||||
other types pack tightly when composed into arrays. The expression
|
||||
you write for a repetition count must be an
|
||||
<A HREF="express.html#arithmetic constant expression" tppabs="http://ccs.ucsd.edu/c/express.html#arithmetic constant expression">arithmetic
|
||||
constant expression</A> whose value is greater than zero.</P>
|
||||
|
||||
<H3><A NAME="Function Types">Function Types</A></H3>
|
||||
|
||||
<P>A <B>function type</B> describes a function whose return value
|
||||
is either an object or an incomplete type other than an array type.
|
||||
A <I><A HREF="#void types">void</A></I> return type
|
||||
indicates that the function returns no result.
|
||||
A function type can also describe the number and types
|
||||
of arguments needed in an expression that
|
||||
<A HREF="express.html#Function Call" tppabs="http://ccs.ucsd.edu/c/express.html#Function Call">calls</A> the function.
|
||||
For example:</P>
|
||||
|
||||
<PRE>
|
||||
double sinh(double x); <B>one double argument,
|
||||
returns double result</B>
|
||||
void wrapup(void); <B>no argument or return value</B></PRE>
|
||||
|
||||
<P>A function type does not represent a value. Instead, it describes
|
||||
how an expression calls (passes control to) a body of executable code.
|
||||
When the function returns (passes control back) to the expression
|
||||
that calls it, it can provide a return value as the value of the function
|
||||
call subexpression.</P>
|
||||
|
||||
<H2><A NAME="Incomplete Types">Incomplete Types</A></H2>
|
||||
|
||||
<P>An <B>incomplete type</B> can be a
|
||||
<A HREF="#Structure Types">structure type</A> whose members
|
||||
you have not yet specified, a
|
||||
<A HREF="#Union Types">union type</A> whose members you have not
|
||||
yet specified, an
|
||||
<A HREF="#Array Types">array type</A> whose repetition count
|
||||
you have not yet specified, or a
|
||||
<I><A HREF="#void types">void</A></I> type.
|
||||
You <I>complete</I> an incomplete
|
||||
type by specifying the missing information.
|
||||
Once completed, an incomplete
|
||||
type becomes an object type.</P>
|
||||
|
||||
<P>You create an
|
||||
<B><A NAME="incomplete structure types">incomplete structure type</A></B>
|
||||
when you declare a
|
||||
<A HREF="#Structure Types">structure type</A>
|
||||
without specifying its members. For example:</P>
|
||||
|
||||
<PRE>
|
||||
struct complex *pc; <B>pc points to incomplete
|
||||
structure type complex</B></PRE>
|
||||
|
||||
<P>You complete an incomplete structure type by declaring the same
|
||||
structure type later in the same scope with its members specified,
|
||||
as in:</P>
|
||||
|
||||
<PRE>
|
||||
struct complex {
|
||||
float re, im;
|
||||
}; <B>complex now completed</B></PRE>
|
||||
|
||||
<P>You create an
|
||||
<B><A NAME="incomplete union types">incomplete union type</A></B>
|
||||
when you declare a
|
||||
<A HREF="#Union Types">union type</A>
|
||||
without specifying its members. For example:</P>
|
||||
|
||||
<PRE>
|
||||
union stuff *ps; <B>ps points to incomplete
|
||||
union type stuff</B></PRE>
|
||||
|
||||
<P>You complete an incomplete union type by declaring the same
|
||||
union type later in the same scope with its members specified, as
|
||||
in:</P>
|
||||
|
||||
<PRE>
|
||||
union stuff {
|
||||
int in;
|
||||
float fl;
|
||||
}; <B>stuff now completed</B></PRE>
|
||||
|
||||
<P>You create an
|
||||
<B><A NAME="incomplete array types">incomplete array type</A></B>
|
||||
when you declare an object that has
|
||||
<A HREF="#Array Types">array type</A> without specifying
|
||||
its repetition count. For example:</P>
|
||||
|
||||
<PRE>
|
||||
char a[]; <B>a has incomplete array type</B></PRE>
|
||||
|
||||
<P>You complete an incomplete array type by redeclaring the same
|
||||
name later in the same scope with the repetition count specified,
|
||||
as in:</P>
|
||||
|
||||
<PRE>
|
||||
char a[25]; <B>a now has complete type</B></PRE>
|
||||
|
||||
<P>You write a
|
||||
<B><A NAME="void types">void type</A></B> as the
|
||||
keyword <CODE>void</CODE>, with an optional (but meaningless)
|
||||
<A HREF="#Type Qualifiers">type qualifier</A>.
|
||||
You can declare but you cannot define an object of <I>void</I> type.
|
||||
You cannot complete a <I>void</I> type.</P>
|
||||
|
||||
<H2><A NAME="Type Qualifiers">Type Qualifiers</A></H2>
|
||||
|
||||
<P>You can <B>qualify</B> any object type or incomplete type with
|
||||
any combination of the two type qualifiers
|
||||
<CODE>const</CODE> and <CODE>volatile</CODE>.
|
||||
Each type qualifier designates a qualified version of some type. The
|
||||
qualified and unqualified versions
|
||||
of a type have the same representation:</P>
|
||||
|
||||
<UL>
|
||||
<LI>A
|
||||
<B><A NAME="const qualifier">const</A></B>-qualified type
|
||||
indicates that access to the designated
|
||||
object cannot alter the value stored in the object. All other object
|
||||
types can have their values altered.</LI>
|
||||
|
||||
<LI>A
|
||||
<B><A NAME="volatile qualifier">volatile</A></B>-qualified type
|
||||
indicates that agencies unknown
|
||||
to the translator can access or alter the value stored in the object.
|
||||
The translator can assume that it has complete control of all objects
|
||||
that do not have <I>volatile</I>-qualified types.</LI>
|
||||
</UL>
|
||||
|
||||
<P>You write a type qualifier within a declaration either as part of the
|
||||
<A HREF="syntax.html#Storage Class and Type Parts" tppabs="http://ccs.ucsd.edu/c/syntax.html#Storage Class and Type Parts">type part</A>
|
||||
or as part of a
|
||||
<A HREF="syntax.html#pointer decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#pointer decoration">pointer decoration</A>.
|
||||
All combinations of pointer
|
||||
decorations and type qualifiers are meaningful. A few examples are:</P>
|
||||
|
||||
<PRE>
|
||||
volatile int vi; <B>vi is a volatile int</B>
|
||||
const int *pci; <B>pci points to const int</B>
|
||||
int *const cpi; <B>cpi is a const pointer to int</B>
|
||||
const int *const cpci; <B>cpci is a const pointer to const int</B>
|
||||
const int *volatile <B>vpci is a volatile pointer</B>
|
||||
vpci; <B>to const int</B></PRE>
|
||||
|
||||
<P>Moreover, all four combinations of type qualifiers are meaningful:</P>
|
||||
|
||||
<UL>
|
||||
<LI>You specify <B>no type qualifiers</B> for the ``normal'' objects
|
||||
in the program.</LI>
|
||||
|
||||
<LI>You specify <B>const-qualified types</B> for objects that the
|
||||
program does not alter (such as tables of constant values).</LI>
|
||||
|
||||
<LI>You specify <B>volatile-qualified types</B> for objects accessed
|
||||
or altered by signal handlers, by concurrently executing programs,
|
||||
or by special hardware (such as a memory-mapped I/O control register).</LI>
|
||||
|
||||
<LI>You specify both <B>const- and volatile-qualified</B>
|
||||
types for objects that the program does not alter, but that other
|
||||
agencies can alter (such as a memory-mapped interval timer).
|
||||
</UL>
|
||||
|
||||
<P>If you declare an object as having a <I>const</I>-qualified
|
||||
type (such as <CODE>cpi</CODE> in the example above), then no expression
|
||||
within the program should attempt to alter the value stored in the
|
||||
object. The implementation can place the object in read-only memory
|
||||
(ROM) or replace references to its stored value with the known value.</P>
|
||||
|
||||
<P>A pointer to <I>const</I>-qualified type can point to an object
|
||||
that does not have <I>const</I>-qualified type. A pointer to a type
|
||||
that is not <I>const</I>-qualified can point to an object that has
|
||||
<I>const</I>-qualified type. You should not, however, alter the value
|
||||
stored in the object with such a pointer.</P>
|
||||
|
||||
<P>For example:</P>
|
||||
|
||||
<PRE>
|
||||
const int ci, *pci;
|
||||
int i, *pi;
|
||||
pci = &i; <B>permissible</B>
|
||||
pi = (int *)&ci; <B>type cast required</B>
|
||||
i = *pci + *pi; <B>permissible</B>
|
||||
*pci = 3; <B>INVALID: *pci is const</B>
|
||||
*pi = 3; <B>INVALID: ci is const</B></PRE>
|
||||
|
||||
<P>If you declare an object as having a <I>volatile</I>-qualified
|
||||
type (such as <CODE>vi</CODE> in the example above), then no expression
|
||||
within the program should access or alter the value stored in the
|
||||
object via an
|
||||
<A HREF="express.html#lvalue expression" tppabs="http://ccs.ucsd.edu/c/express.html#lvalue expression">lvalue</A>
|
||||
that does not have a <I>volatile</I>-qualified type.</P>
|
||||
|
||||
<P>A pointer to <I>volatile</I>-qualified type can point to an
|
||||
object that does not have <I>volatile</I>-qualified type. A pointer
|
||||
to a type that is not <I>volatile</I>-qualified can point to an object
|
||||
that has <I>volatile</I>-qualified type. You should not, however,
|
||||
access the object with such a pointer.</P>
|
||||
|
||||
<H2><A NAME="Compatible and Composite Types">Compatible and Composite Types</A></H2>
|
||||
|
||||
<P>In many contexts, the translator must test whether two types
|
||||
are <B>compatible</B>, which occurs when one of the following conditions
|
||||
is met:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Both types are the same.</LI>
|
||||
|
||||
<LI>Both are
|
||||
<A HREF="#Pointer Types">pointer types</A>,
|
||||
with the same type qualifiers, that
|
||||
point to compatible types.</LI>
|
||||
|
||||
<LI>Both are
|
||||
<A HREF="#Array Types">array types</A>
|
||||
whose elements have compatible types. If
|
||||
both specify repetition counts, the repetition counts are equal.</LI>
|
||||
|
||||
<LI>Both are
|
||||
<A HREF="#Function Types">function types</A>
|
||||
whose return types are compatible. If
|
||||
both specify types for their parameters, both
|
||||
<A HREF="function.html#Function Declarations" tppabs="http://ccs.ucsd.edu/c/function.html#Function Declarations">declare</A> the same number
|
||||
of parameters (including ellipses) and the types of corresponding
|
||||
parameters are compatible.
|
||||
Otherwise, at least one does not specify types for
|
||||
its parameters. If the other specifies types for its parameters, it
|
||||
specifies only a fixed number of parameters
|
||||
and does not specify parameters of type
|
||||
<I><A HREF="#float type">float</A></I> or of any
|
||||
<A HREF="#integer types">integer types</A> that change when
|
||||
<A HREF="express.html#Promoting" tppabs="http://ccs.ucsd.edu/c/express.html#Promoting">promoted</A>.</LI>
|
||||
|
||||
<LI>Both are
|
||||
<A HREF="#Structure Types">structure</A>,
|
||||
<A HREF="#Union Types">union</A>, or
|
||||
<A HREF="#Enumerations">enumeration</A> types that are declared
|
||||
in different translation units with the same member names. Structure
|
||||
members are declared in the same order. Structure and union members
|
||||
whose names match are declared with compatible types. Enumeration
|
||||
constants whose names match have the same values.</LI>
|
||||
</UL>
|
||||
|
||||
<P>Some examples of compatible types are:</P>
|
||||
|
||||
<PRE>
|
||||
long <B>is compatible with</B> long
|
||||
long <B>is compatible with</B> signed long
|
||||
char a[] <B>is compatible with</B> char a[10]
|
||||
int f(int i) <B>is compatible with</B> int f()</PRE>
|
||||
|
||||
<P>Two types are
|
||||
<B><A NAME="assignment compatible">assignment compatible</A></B>
|
||||
if they form a valid combination of types for the
|
||||
<A HREF="express.html#Assignment" tppabs="http://ccs.ucsd.edu/c/express.html#Assignment">assignment</A>
|
||||
operator (<CODE>=</CODE>).</P>
|
||||
|
||||
<P>The translator combines compatible types to form a
|
||||
<B>composite type</B>. The composite type is determined
|
||||
in one of the following ways:</P>
|
||||
|
||||
<UL>
|
||||
<LI>For two types that are the same, it is the common type.</LI>
|
||||
|
||||
<LI>For two
|
||||
<A HREF="#Pointer Types">pointer types</A>,
|
||||
it is a similarly qualified pointer to
|
||||
the composite type pointed to.</LI>
|
||||
|
||||
<LI>For two
|
||||
<A HREF="#Array Types">array types</A>,
|
||||
it is an array of elements with the composite
|
||||
of the two element types. If one of the array types specifies a repetition
|
||||
count, that type provides the repetition count for the composite type.
|
||||
Otherwise, the composite has no repetition count.</LI>
|
||||
|
||||
<LI>For two
|
||||
<A HREF="#Function Types">function types</A>,
|
||||
it is a function type that returns a
|
||||
composite of the two return types. If both specify types for their
|
||||
parameters, each parameter type in the composite type is the composite
|
||||
of the two corresponding parameter types. If only one specifies types
|
||||
for its parameters, it determines the parameter types in the composite
|
||||
type. Otherwise, the composite type
|
||||
specifies no types for its parameters.</LI>
|
||||
|
||||
<LI>For two
|
||||
<A HREF="#Structure Types">structure</A>,
|
||||
<A HREF="#Union Types">union</A>, or
|
||||
<A HREF="#Enumerations">enumeration</A> types, it is the type
|
||||
declared in the current translation unit.</LI>
|
||||
</UL>
|
||||
|
||||
<P>For example, the following two types are compatible:</P>
|
||||
|
||||
<PRE>
|
||||
FILE *openit(char *) <B>and</B> FILE *openit()</PRE>
|
||||
|
||||
<P>They have the composite type:</P>
|
||||
|
||||
<PRE>
|
||||
FILE *openit(char *)</PRE>
|
||||
|
||||
<P>For a more complex example, the two types:</P>
|
||||
|
||||
<PRE>
|
||||
void (*apf[])(int x) <B>and</B> void (*apf[20])()</PRE>
|
||||
|
||||
<P>are compatible and have the composite type:</P>
|
||||
|
||||
<PRE>
|
||||
void (*apf[20])(int x)</PRE>
|
||||
|
||||
<HR>
|
||||
<P>See also the
|
||||
<B><A HREF="index.html#Table of Contents" tppabs="http://ccs.ucsd.edu/c/index.html#Table of Contents">Table of Contents</A></B> and the
|
||||
<B><A HREF="_index.html" tppabs="http://ccs.ucsd.edu/c/_index.html">Index</A></B>.</P>
|
||||
|
||||
<P><I>
|
||||
<A HREF="crit_pb.html" tppabs="http://ccs.ucsd.edu/c/crit_pb.html">Copyright</A> © 1989-1996
|
||||
by P.J. Plauger and Jim Brodie. All rights reserved.</I></P>
|
||||
|
||||
</BODY></HTML>
|
||||
|
||||
Reference in New Issue
Block a user