add directory Ref-docs

This commit is contained in:
gohigh
2024-02-19 00:21:47 -05:00
parent 5a46ddb732
commit ef50495c9d
2492 changed files with 1609142 additions and 0 deletions

810
Ref-docs/C/types.html Normal file
View 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>
&#183; <A HREF="#Arithmetic Types">Arithmetic Types</A>
&#183; <A HREF="#Basic Integer Types">Basic Integer Types</A>
&#183; <A HREF="#Bitfields">Bitfields</A>
&#183; <A HREF="#Enumerations">Enumerations</A>
&#183; <A HREF="#Floating-Point Types">Floating-Point Types</A>
&#183; <A HREF="#Deriving Types">Deriving Types</A>
&#183; <A HREF="#Pointer Types">Pointer Types</A>
&#183; <A HREF="#Structure Types">Structure Types</A>
&#183; <A HREF="#Union Types">Union Types</A>
&#183; <A HREF="#Array Types">Array Types</A>
&#183; <A HREF="#Function Types">Function Types</A>
&#183; <A HREF="#Incomplete Types">Incomplete Types</A>
&#183; <A HREF="#Type Qualifiers">Type Qualifiers</A>
&#183; <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 = &amp;x; <B>DANGEROUS PRACTICE</B></PRE>
<P>not all translators treat <CODE>&amp;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 = &amp;i; <B>permissible</B>
pi = (int *)&amp;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> &#169; 1989-1996
by P.J. Plauger and Jim Brodie. All rights reserved.</I></P>
</BODY></HTML>