Files
oldlinux-files/study/Ref-docs/C/portable.html
2024-02-19 00:25:23 -05:00

744 lines
39 KiB
HTML

<HTML><HEAD><TITLE>Portability</TITLE></HEAD><BODY BGCOLOR="#FFFFFF">
<H1><A NAME="Portability">Portability</A></H1><HR>
<P><B><A HREF="#Writing Portable Programs">Writing Portable Programs</A>
&#183; <A HREF="#Translation-Time Issues">Translation-Time Issues</A>
&#183; <A HREF="#Character-Set Issues">Character-Set Issues</A>
&#183; <A HREF="#Representation Issues">Representation Issues</A>
&#183; <A HREF="#Expression-Evaluation Issues">Expression-Evaluation Issues</A>
&#183; <A HREF="#Library Issues">Library Issues</A>
&#183; <A HREF="#Converting to Standard C">Converting to Standard C</A>
&#183; <A HREF="#Function-Call Issues">Function-Call Issues</A>
&#183; <A HREF="#Preprocessing Issues">Preprocessing Issues</A>
&#183; <A HREF="#Library Issues">Library Issues</A>
&#183; <A HREF="#Quiet Changes">Quiet Changes</A>
&#183; <A HREF="#Newer Dialects">Newer Dialects</A>
</B></P>
<HR>
<P>A <B>portable</B> program is one that you can move with little
or no extra investment of effort to a computer that differs from the
one on which you originally developed the program. Writing a program in
<A HREF="index.html#Standard C" tppabs="http://ccs.ucsd.edu/c/index.html#Standard C">Standard C</A>
does not guarantee that it will be portable. You must
be aware of the aspects of the program that can vary among implementations.
You can then write the program so that it does not depend critically
on implementation-specific aspects.</P>
<P>This document describes what you must be aware of when writing
a portable program. It also tells you what to look for when you alter
programs written in older dialects of C so that they behave properly
under a Standard C implementation. It briefly
summarizes the features added with
<A HREF="lib_over.html#Amendment 1" tppabs="http://ccs.ucsd.edu/c/lib_over.html#Amendment 1">Amendment 1</A>
to the C Standard. And it suggests ways to
write C code that is also valid as C++ code.</P>
<H2><A NAME="Writing Portable Programs">Writing Portable Programs</A></H2>
<P>Although the language definition specifies most aspects of Standard
C, it intentionally leaves some aspects unspecified. The language
definition also permits other aspects to vary among implementations.
If the program depends on behavior that is not fully specified or
that can vary among implementations, then there is a good chance that
you will need to alter the program when you move it to another
computer.</P>
<P>This section identifies issues that affect portability, such
as how the translator interprets the program and how the target environment
represents files. The list of issues is not complete, but it does
include the common issues that you confront when you write a portable
program.</P>
<P>An implementation of Standard C must include a document that
describes any behavior that is
<B><A NAME="implementation defined">implementation defined</A></B>. You
should read this document to be aware of those aspects that can vary,
to be alert to behavior that can be peculiar to a particular implementation,
and to take advantage of special features in programs that need not
be portable.</P>
<H3><A NAME="Translation-Time Issues">Translation-Time Issues</A></H3>
<P>A program can depend on peculiar properties of the translator.</P>
<P>The
<A HREF="lib_over.html#filename" tppabs="http://ccs.ucsd.edu/c/lib_over.html#filename">filenames</A> acceptable to an
<A HREF="preproc.html#Include Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Include Directives"><I>include</I> directive</A> can
vary considerably among implementations. If you use filenames that
consist of other than six letters (of a single case), followed by
a dot (<CODE>.</CODE>), followed by a single letter, then an implementation
can find the name unacceptable. Each implementation defines the filenames
that you can create.</P>
<P>How preprocessing uses a filename
to locate a file can also vary. Each
<A HREF="#implementation defined">implementation defines</A>
where you must place files that
you want to include with an <I>include</I> directive.</P>
<P>If you write two or more of the operators <CODE>##</CODE> within a
macro definition, the order in which preprocessing
<A HREF="preproc.html#Expanding Macros" tppabs="http://ccs.ucsd.edu/c/preproc.html#Expanding Macros">concatenates tokens</A>
can vary. If any order produces an invalid preprocessing token as
an intermediate result, the program can misbehave when you move it.</P>
<P>A translator can limit the size and complexity of a program
that it can translate. Such limits can also depend on the environment
in which the translator executes. Thus, no translation unit you write
can assuredly survive all Standard C translators. Obey the following
individual limits, however, to ensure the highest probability of success:</P>
<UL>
<LI>Nest statements -- such as
<A HREF="function.html#If Statement" tppabs="http://ccs.ucsd.edu/c/function.html#If Statement"><I>if</I></A> and
<A HREF="function.html#While Statement" tppabs="http://ccs.ucsd.edu/c/function.html#While Statement"><I>while</I> statements</A>
-- no more than fifteen levels deep. The braces surrounding a block
add a level of nesting.</LI>
<LI>Nest
<A HREF="preproc.html#Conditional Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Conditional Directives">conditional directives</A>
-- such as
<A HREF="preproc.html#if directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#if directive"><I>if</I></A> and
<A HREF="preproc.html#ifdef directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#ifdef directive"><I>ifdef</I> directives</A>
-- no more than eight levels deep.</LI>
<LI>Add no more than twelve decorations -- to derive
<A HREF="syntax.html#pointer decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#pointer decoration">pointer</A>,
<A HREF="syntax.html#array decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#array decoration">array</A>, and
<A HREF="syntax.html#function decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#function decoration">function</A> types --
to a declarator.</LI>
<LI>Write no more than 31 nested pairs of parentheses in a
<A HREF="syntax.html#Declarators" tppabs="http://ccs.ucsd.edu/c/syntax.html#Declarators">declarator</A>.</LI>
<LI>Write no more than 32 nested pairs of parentheses within an
<A HREF="syntax.html#Expression Syntax" tppabs="http://ccs.ucsd.edu/c/syntax.html#Expression Syntax">expression</A>.</LI>
<LI>Ensure that all distinct
<A HREF="syntax.html#name" tppabs="http://ccs.ucsd.edu/c/syntax.html#name">names</A> differ in their first 31 characters.
Also ensure that all characters match for names that the translator
should treat as the same.</LI>
<LI>Ensure that all
<B><A NAME="distinct external names">distinct names</A></B> with
<A HREF="declare.html#external linkage" tppabs="http://ccs.ucsd.edu/c/declare.html#external linkage">external linkage</A> differ
in the first six characters, even if the translator converts all letters
to a single case. Also ensure that all characters match for such names
that the translator should treat as the same.</LI>
<LI>Write no more than 511 distinct names with
<A HREF="declare.html#external linkage" tppabs="http://ccs.ucsd.edu/c/declare.html#external linkage">external linkage</A>
within a translation unit.</LI>
<LI>Write no more than 127 distinct names in
<A HREF="declare.html#block-level declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#block-level declaration">block-level declarations</A>
that share a single name space.</LI>
<LI>Define no more than 1,024 distinct names as
<A HREF="preproc.html#Define Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Define Directives">macros</A> at any point
within a translation unit.</LI>
<LI>Write no more than 31 parameters in a
<A HREF="syntax.html#function decoration" tppabs="http://ccs.ucsd.edu/c/syntax.html#function decoration">function decoration</A>.</LI>
<LI>Write no more than 31 arguments in a
<A HREF="function.html#Function Calls" tppabs="http://ccs.ucsd.edu/c/function.html#Function Calls">function call</A>.</LI>
<LI>Write no more than 31 parameters in a
<A HREF="preproc.html#Define Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Define Directives">macro definition</A>.</LI>
<LI>Write no more than 31 arguments in a
<A HREF="preproc.html#Expanding Macros" tppabs="http://ccs.ucsd.edu/c/preproc.html#Expanding Macros">macro invocation</A>.</LI>
<LI>Write no
<A HREF="preproc.html#logical line" tppabs="http://ccs.ucsd.edu/c/preproc.html#logical line">logical</A>
source line that exceeds 509 characters.</LI>
<LI>Construct no
<A HREF="preproc.html#string literal" tppabs="http://ccs.ucsd.edu/c/preproc.html#string literal">string literal</A>
that contains more than 509 characters or wide characters.</LI>
<LI>Declare no
<A HREF="declare.html#Object Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Object Declaration">object</A>
whose size exceeds 32,767 bytes.</LI>
<LI>Ensure that
<A HREF="preproc.html#Include Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Include Directives"><I>include</I> directives</A>
nest no more than eight files deep.</LI>
<LI>Write no more than 257
<A HREF="function.html#Case Label" tppabs="http://ccs.ucsd.edu/c/function.html#Case Label"><I>case</I> labels</A> for any one
<A HREF="function.html#Switch Statement" tppabs="http://ccs.ucsd.edu/c/function.html#Switch Statement"><I>switch</I> statement</A>.
(<I>Case</I> labels within nested <I>switch</I> statements
do not affect this limit.)</LI>
<LI>Write no more than 127
<A HREF="declare.html#Member Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Member Declaration">members</A>
in any one structure or union.</LI>
<LI>Write no more than 127
<A HREF="types.html#enumeration constants" tppabs="http://ccs.ucsd.edu/c/types.html#enumeration constants">enumeration constants</A>
in any one enumeration.</LI>
<LI>Nest structure or union definitions no more than fifteen deep
in any one list of
<A HREF="declare.html#Member Declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#Member Declaration">member declarations</A>.</LI>
</UL>
<H3><A NAME="Character-Set Issues">Character-Set Issues</A></H3>
<P>The program can depend on peculiar properties of the <B>character
set</B>.</P>
<P>If you write in the source files any characters not in the
<A HREF="charset.html#basic C character set" tppabs="http://ccs.ucsd.edu/c/charset.html#basic C character set">basic C character set</A>,
a corresponding character might not be in another
character set, or the corresponding character might not be what you
want. The set of characters is
<A HREF="#implementation defined">defined</A> for each implementation.</P>
<P>Similarly, if the program makes special use of characters not
in the basic C character set when it executes, you might get different
behavior when you move the program.</P>
<P>If you write a
<A HREF="charset.html#character constant" tppabs="http://ccs.ucsd.edu/c/charset.html#character constant">character constant</A>
that specifies more than one character,
such as <CODE>'ab'</CODE>, the result might change when you move
the program. Each implementation
<A HREF="#implementation defined">defines</A> what values it assigns such
character constants.</P>
<P>If the program depends on a particular value for one or more
character codes, it can behave differently
on an implementation with a different
<A HREF="charset.html#Character Sets" tppabs="http://ccs.ucsd.edu/c/charset.html#Character Sets">character set</A>.
The codes associated with each character
are implementation defined.</P>
<H3><A NAME="Representation Issues">Representation Issues</A></H3>
<P>The program can depend on how an implementation <B>represents</B> objects.
All representations are implementation defined.</P>
<P>If the program depends on the representation of an object type
(such as its size in bits or whether type
<A HREF="types.html#Basic Integer Types" tppabs="http://ccs.ucsd.edu/c/types.html#Basic Integer Types"><I>char</I></A> or the plain
<A HREF="types.html#Bitfields" tppabs="http://ccs.ucsd.edu/c/types.html#Bitfields"><I>bitfield</I></A>
types can represent negative values), the program
can change behavior when you move it.</P>
<P>If you treat an arithmetic object that has more than one byte
as an array of characters, you must be aware that the order of significant
bytes can vary among implementations. You cannot write an integer
or floating-point type object to a
<A HREF="lib_file.html#binary stream" tppabs="http://ccs.ucsd.edu/c/lib_file.html#binary stream">binary stream</A>
on one implementation,
then later read those bytes into an object of the same type on a different
implementation, and portably obtain the same stored value.</P>
<P>The method of encoding integer and floating-point values can
vary widely. For
<A HREF="types.html#Basic Integer Types" tppabs="http://ccs.ucsd.edu/c/types.html#Basic Integer Types">signed integer types</A>,
negative values have several popular encodings.
<A HREF="types.html#Floating-Point Types" tppabs="http://ccs.ucsd.edu/c/types.html#Floating-Point Types">Floating-point types</A>
have numerous popular encodings.
This means that, except for the minimum guaranteed range of values
for each type, the range of values can vary widely.</P>
<P>Both signed integer and floating-point types
can have values that represent an
<A HREF="express.html#exceptional result" tppabs="http://ccs.ucsd.edu/c/express.html#exceptional result">exceptional result</A>
on some implementations. Performing an arithmetic operation
or a comparison on such a value can report a
<A HREF="signal.html#signals" tppabs="http://ccs.ucsd.edu/c/signal.html#signals">signal</A> or otherwise
<A HREF="lib_over.html#program termination" tppabs="http://ccs.ucsd.edu/c/lib_over.html#program termination">terminate execution</A>.
Initialize all such objects before accessing them --
and avoid overflow, underflow, or zero divide --
to avoid exceptional results.</P>
<P>The alignment requirements of various object types can vary
widely. The placement and size of
<A HREF="types.html#holes" tppabs="http://ccs.ucsd.edu/c/types.html#holes">holes</A> in structures is
<A HREF="#implementation defined">implementation defined</A>.
You can portably determine the offset of a given member from the beginning
of a structure, but only by using the
<A HREF="stddef.html#offsetof" tppabs="http://ccs.ucsd.edu/c/stddef.html#offsetof"><CODE>offsetof</CODE></A> macro.</P>
<P>Each implementation defines how
<A HREF="types.html#Bitfields" tppabs="http://ccs.ucsd.edu/c/types.html#Bitfields">bitfields</A> pack into integer
objects and whether bitfields can straddle two or more underlying
objects. You can declare bitfields of 16 bits
or less in all implementations.</P>
<P>How an implementation represents
<A HREF="types.html#Enumerations" tppabs="http://ccs.ucsd.edu/c/types.html#Enumerations">enumeration</A> types can vary.
You can be certain that all enumeration constants can be represented
as type <I>int.</I></P>
<H3><A NAME="Expression-Evaluation Issues">Expression-Evaluation Issues</A></H3>
<P>The program can depend on how an implementation
<B>evaluates expressions</B>.</P>
<P>The order in which the program evaluates subexpressions can
vary widely, subject to the limits imposed by the
<A HREF="express.html#sequence point" tppabs="http://ccs.ucsd.edu/c/express.html#sequence point">sequence points</A>
within and between expressions. Therefore, the timing and order of
<A HREF="function.html#side effects" tppabs="http://ccs.ucsd.edu/c/function.html#side effects">side effects</A>
can vary between any two sequence points. A common error
is to depend on a particular order for the evaluation of argument
expressions on a
<A HREF="function.html#Function Calls" tppabs="http://ccs.ucsd.edu/c/function.html#Function Calls">function call</A>.
Any order is permissible.</P>
<P>Whether you can usefully
<A HREF="express.html#Assigning and Type Casting" tppabs="http://ccs.ucsd.edu/c/express.html#Assigning and Type Casting">type cast</A>
a pointer value to an integer
value or type cast a nonzero integer value to a pointer value depends
on the implementation. Each implementation
<A HREF="#implementation defined">defines</A> how it converts
between scalar types.</P>
<P>If the quotient of an integer
<A HREF="express.html#Divide" tppabs="http://ccs.ucsd.edu/c/express.html#Divide">division</A> is negative, the sign
of a nonzero remainder can be either positive or negative. The result
is implementation defined. Use the
<A HREF="stdlib.html#div" tppabs="http://ccs.ucsd.edu/c/stdlib.html#div"><CODE>div</CODE></A> and
<A HREF="stdlib.html#ldiv" tppabs="http://ccs.ucsd.edu/c/stdlib.html#ldiv"><CODE>ldiv</CODE></A> functions
for consistent behavior across implementations.</P>
<P>When the program
<A HREF="express.html#Right Shift" tppabs="http://ccs.ucsd.edu/c/express.html#Right Shift">right shifts</A>
a negative integer value, different
implementations can define different results. To get consistent results
across implementations, you can right shift only positive (or unsigned)
integer values.</P>
<P>When the program
<A HREF="express.html#Changing Representations" tppabs="http://ccs.ucsd.edu/c/express.html#Changing Representations">converts</A>
a <I>long double</I> value to another
floating-point type, or a <I>double</I> to a <I>float,</I> it can
round the result to either a nearby higher or a nearby lower representation
of the original value. Each implementation
<A HREF="#implementation defined">defines</A> how such conversions
behave.</P>
<P>When the program accesses or stores a value in a
<A HREF="types.html#Type Qualifiers" tppabs="http://ccs.ucsd.edu/c/types.html#Type Qualifiers"><I>volatile</I></A>
object, each implementation defines the number and nature of the accesses
and stores. Three possibilities exist:</P>
<UL>
<LI>multiple accesses to different bytes</LI>
<LI>multiple accesses to the same byte</LI>
<LI>no accesses at all</LI>
</UL>
<P>You cannot write a program that assuredly produces the same
pattern of accesses across multiple implementations.</P>
<P>The expansion of the
<A HREF="types.html#null pointer value" tppabs="http://ccs.ucsd.edu/c/types.html#null pointer value">null pointer</A> constant macro
<A HREF="stddef.html#NULL" tppabs="http://ccs.ucsd.edu/c/stddef.html#NULL"><CODE>NULL</CODE></A>
can be any of <CODE>0</CODE>, <CODE>0L</CODE>, or <CODE>(void *)0</CODE>.
The program should not depend on a particular choice.
You should not assign <CODE>NULL</CODE>
to a pointer to a function, and you should not use <CODE>NULL</CODE> as
an argument to a function call that has no
<A HREF="function.html#function prototypes" tppabs="http://ccs.ucsd.edu/c/function.html#function prototypes">type information</A> for the
corresponding parameter.</P>
<P>The actual integer types corresponding to the type definitions
<A HREF="stddef.html#ptrdiff_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#ptrdiff_t"><CODE>ptrdiff_t</CODE></A>,
<A HREF="stddef.html#size_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#size_t"><CODE>size_t</CODE></A>, and
<A HREF="stddef.html#wchar_t" tppabs="http://ccs.ucsd.edu/c/stddef.html#wchar_t"><CODE>wchar_t</CODE></A> can vary.
Use the type definitions.</P>
<H3><A NAME="Library Issues">Library Issues</A></H3>
<P>The behavior of the
<A HREF="index.html#Standard C Library" tppabs="http://ccs.ucsd.edu/c/index.html#Standard C Library">Standard C library</A> can vary.</P>
<P>What happens to the
<A HREF="lib_file.html#file-position indicator" tppabs="http://ccs.ucsd.edu/c/lib_file.html#file-position indicator">file-position indicator</A>
for a <A HREF="lib_file.html#text stream" tppabs="http://ccs.ucsd.edu/c/lib_file.html#text stream">text stream</A>
immediately after a successful call to
<A HREF="stdio.html#ungetc" tppabs="http://ccs.ucsd.edu/c/stdio.html#ungetc"><CODE>ungetc</CODE></A> is not defined.
Avoid mixing
<A HREF="lib_file.html#position functions" tppabs="http://ccs.ucsd.edu/c/lib_file.html#position functions">file-positioning operations</A>
with calls to this function.</P>
<P>When the function
<A HREF="stdlib.html#bsearch" tppabs="http://ccs.ucsd.edu/c/stdlib.html#bsearch"><CODE>bsearch</CODE></A>
can match either of two equal elements of an array,
different implementations can return different matches.</P>
<P>When the function
<A HREF="stdlib.html#qsort" tppabs="http://ccs.ucsd.edu/c/stdlib.html#qsort"><CODE>qsort</CODE></A>
sorts an array containing two
elements that compare equal, different implementations can leave the
elements in different order.</P>
<P>Whether or not floating-point
<B><A NAME="underflow">underflow</A></B> causes the value
<A HREF="errno.html#ERANGE" tppabs="http://ccs.ucsd.edu/c/errno.html#ERANGE"><CODE>ERANGE</CODE></A> to be stored in
<A HREF="errno.html#errno" tppabs="http://ccs.ucsd.edu/c/errno.html#errno"><CODE>errno</CODE></A>
(as the result of a
<A HREF="math.html#range error" tppabs="http://ccs.ucsd.edu/c/math.html#range error">range error</A>) can vary.
Each implementation defines how it handles floating-point underflow.</P>
<P>What library functions store values in <CODE>errno</CODE>
varies considerably.
To determine whether the function of interest reported an error, you
must store the value zero in <CODE>errno</CODE> before you call a library
function and then test the stored value before you call another library
function.</P>
<P>You can do very little with
<A HREF="signal.html#signals" tppabs="http://ccs.ucsd.edu/c/signal.html#signals">signals</A> in a portable program. A
target environment can elect not to report signals. If it does report
signals, any handler you write for an asynchronous signal can only:</P>
<UL>
<LI>make a successful call to
<A HREF="signal.html#signal" tppabs="http://ccs.ucsd.edu/c/signal.html#signal"><CODE>signal</CODE></A> for that particular
signal</LI>
<LI>alter the value stored in an object of type <CODE>volatile
<A HREF="signal.html#sig_atomic_t" tppabs="http://ccs.ucsd.edu/c/signal.html#sig_atomic_t">sig_atomic_t</A></CODE></LI>
<LI>return control to its caller</LI>
</UL>
<P>Asynchronous signals can disrupt proper operation of the library.
Avoid using signals, or tailor how you use them
to each target environment.</P>
<P><A HREF="lib_scan.html#Scan Functions" tppabs="http://ccs.ucsd.edu/c/lib_scan.html#Scan Functions">Scan functions</A>
can give special meaning to a minus (<CODE>-</CODE>)
that is not the first or the last character of a
<A HREF="lib_scan.html#scan set" tppabs="http://ccs.ucsd.edu/c/lib_scan.html#scan set">scan set</A>. The behavior is
<A HREF="#implementation defined">implementation defined</A>.
Write this character only first or last in a scan set.</P>
<P>If you allocate an object of zero size by calling one of the functions
<A HREF="stdlib.html#calloc" tppabs="http://ccs.ucsd.edu/c/stdlib.html#calloc"><CODE>calloc</CODE></A>,
<A HREF="stdlib.html#malloc" tppabs="http://ccs.ucsd.edu/c/stdlib.html#malloc"><CODE>malloc</CODE></A>, or
<A HREF="stdlib.html#realloc" tppabs="http://ccs.ucsd.edu/c/stdlib.html#realloc"><CODE>realloc</CODE></A>, the behavior is
<A HREF="#implementation defined">implementation defined</A>.
Avoid such calls.</P>
<P>If you call the function
<A HREF="stdlib.html#exit" tppabs="http://ccs.ucsd.edu/c/stdlib.html#exit"><CODE>exit</CODE></A> with a status argument
value other than zero (for successful termination),
<A HREF="stdlib.html#EXIT_FAILURE" tppabs="http://ccs.ucsd.edu/c/stdlib.html#EXIT_FAILURE"><CODE>EXIT_FAILURE</CODE></A>, or
<A HREF="stdlib.html#EXIT_SUCCESS" tppabs="http://ccs.ucsd.edu/c/stdlib.html#EXIT_SUCCESS"><CODE>EXIT_SUCCESS</CODE></A>,
the behavior is
<A HREF="#implementation defined">implementation defined</A>. Use
only these values to report status.</P>
<H2><A NAME="Converting to Standard C">Converting to Standard C</A></H2>
<P>If you have a program written in an earlier dialect of C that
you want to convert to Standard C, be aware of all the portability
issues described earlier in this document. You must also be aware
of issues peculiar to earlier dialects of C. Standard C tries to codify
existing practice wherever possible, but existing practice varied
in certain areas. This section discusses the major areas to address
when moving an older C program to a Standard C environment.</P>
<H3><A NAME="Function-Call Issues">Function-Call Issues</A></H3>
<P>In earlier dialects of C, you cannot write a
<A HREF="function.html#function prototypes" tppabs="http://ccs.ucsd.edu/c/function.html#function prototypes">function prototype</A>.
Function types do not have argument information, and function calls
occur in the absence of any argument information. Many implementations
let you call any function with a
<A HREF="stdarg.html#varying number of arguments" tppabs="http://ccs.ucsd.edu/c/stdarg.html#varying number of arguments">varying number
of arguments</A>.</P>
<P>You can directly address many of the potential difficulties
in converting a program to Standard C by writing function prototypes
for all functions. Declare functions with
<A HREF="declare.html#external linkage" tppabs="http://ccs.ucsd.edu/c/declare.html#external linkage">external linkage</A> that you
use in more than one file in a separate file, and then include that
file in all source files that call or define the functions.</P>
<P>The translator will check that function calls and function definitions
are consistent with the function prototypes that you write. It will
emit a diagnostic if you call a function with an incorrect number
of arguments. It will emit a diagnostic if you call a function with
an argument expression that is not
<A HREF="types.html#assignment compatible" tppabs="http://ccs.ucsd.edu/c/types.html#assignment compatible">assignment compatible</A>
with the corresponding function parameter. It will
<A HREF="express.html#Assigning and Type Casting" tppabs="http://ccs.ucsd.edu/c/express.html#Assigning and Type Casting">convert</A>
an argument expression that is assignment compatible
but that does not have the same type
as the corresponding function parameter.</P>
<P>Older C programs often rely on argument values of different
types having the same representation on a given implementation. By
providing function prototypes, you can ensure that the translator
will diagnose, or quietly correct, any function calls for which the
representation of an argument value is not always acceptable.</P>
<P>For functions intended to accept a varying number of arguments,
different implementations provide different methods of accessing the
unnamed arguments. When you identify such a function, declare it with
the ellipsis notation, such as <CODE>int f(int x, ...)</CODE>. Within the
function, use the macros defined in
<A HREF="stdarg.html" tppabs="http://ccs.ucsd.edu/c/stdarg.html"><CODE>&lt;stdarg.h&gt;</CODE></A> to replace the
existing method for accessing unnamed arguments.</P>
<H3><A NAME="Preprocessing Issues">Preprocessing Issues</A></H3>
<P>Perhaps the greatest variation in dialects among earlier implementations
of C occurs in preprocessing. If the program
<A HREF="preproc.html#Define Directives" tppabs="http://ccs.ucsd.edu/c/preproc.html#Define Directives">defines macros</A> that perform
only simple substitutions of preprocessing tokens, then you can expect
few problems. Otherwise, be wary of variations in several areas.</P>
<P>Some earlier dialects
<A HREF="preproc.html#Expanding Macros" tppabs="http://ccs.ucsd.edu/c/preproc.html#Expanding Macros">expand macro</A>
arguments after substitution, rather than before.
This can lead to differences in how a macro expands
when you write other macro invocations within its arguments.</P>
<P>Some earlier dialects do not rescan the replacement token sequence
after substitution. Macros that expand to macro invocations work differently,
depending on whether the rescan occurs.</P>
<P>Dialects that rescan the replacement token sequence work differently,
depending on whether a macro that expands to a macro invocation can
involve preprocessing tokens in the text following the macro invocation.</P>
<P>The handling of a macro name during an expansion of its invocation
varies considerably.</P>
<P>Some dialects permit empty argument sequences in a macro invocation.
Standard C does not always permit empty arguments.</P>
<P>The concatenation of tokens with the operator <CODE>##</CODE> is new
with Standard C. It replaces several earlier methods.</P>
<P>The
<A HREF="preproc.html#Creating String Literals" tppabs="http://ccs.ucsd.edu/c/preproc.html#Creating String Literals">creation of
string literals</A> with the operator <CODE>#</CODE> is
new with Standard C. It replaces the practice in some earlier dialects
of substituting macro parameter names that you write within string
literals in macro definitions.</P>
<H3><A NAME="Library Issues">Library Issues</A></H3>
<P>The
<A HREF="index.html#Standard C Library" tppabs="http://ccs.ucsd.edu/c/index.html#Standard C Library">Standard C library</A>
is largely a superset of existing libraries.
Some conversion problems, however, can occur.</P>
<P>Many earlier implementations offer an additional set of input/output
functions with names such as <CODE>close</CODE>,
<CODE>creat</CODE>, <CODE>lseek</CODE>,
<CODE>open</CODE>, <CODE>read</CODE>, and <CODE>write</CODE>.
You must replace calls to these functions
with calls to other functions defined in
<A HREF="stdio.html" tppabs="http://ccs.ucsd.edu/c/stdio.html"><CODE>&lt;stdio.h&gt;</CODE></A>.</P>
<P>Standard C has several minor changes in the behavior of library
functions, compared with popular earlier dialects. These changes generally
occur in areas where practice also varied.</P>
<H3><A NAME="Quiet Changes">Quiet Changes</A></H3>
<P>Most differences between Standard C and earlier dialects of
C cause a Standard C translator to emit a diagnostic when it encounters
a program written in the earlier dialect of C. Some changes, unfortunately,
require no diagnostic. What was a valid program in the earlier dialect
is also a valid program in Standard C, but with different meaning.</P>
<P>While these <B>quiet changes</B> are few in number and generally
subtle, you need to be aware of them. They occasionally give rise
to unexpected behavior in a program that you convert to Standard C.
The principal quiet changes are discussed below.</P>
<P><A HREF="charset.html#Trigraphs" tppabs="http://ccs.ucsd.edu/c/charset.html#Trigraphs">Trigraphs</A>
do not occur in earlier dialects of C. An older program
that happens to contain a sequence of two question marks (<CODE>??</CODE>)
can change meaning in a variety of ways.</P>
<P>Some earlier dialects effectively promote any declaration you
write that has external linkage to file level. Standard C keeps such
declarations at block level.</P>
<P>Earlier dialects of C let you use the digits
<CODE>8</CODE> and <CODE>9</CODE> in an
<A HREF="charset.html#octal escape sequence" tppabs="http://ccs.ucsd.edu/c/charset.html#octal escape sequence">octal escape sequence</A>,
such as in the string literal <CODE>"\08"</CODE>.
Standard C treats this as a string literal with two characters (plus
the terminating null character).</P>
<P><A HREF="charset.html#hexadecimal escape sequence" tppabs="http://ccs.ucsd.edu/c/charset.html#hexadecimal escape sequence">Hexadecimal
escape sequences</A>, such as <CODE>\xff</CODE>, and the escape
sequence <CODE>\a</CODE> are new with Standard C.
In certain earlier implementations, they may have different meaning.</P>
<P>Some earlier dialects guarantee that identical
<A HREF="charset.html#string literal" tppabs="http://ccs.ucsd.edu/c/charset.html#string literal">string literals</A>
share common storage, and others guarantee that they do not. Some
dialects let you alter the values stored in string literals. You cannot
be certain that identical string literals overlap in Standard C,
or that they do not. Do
not alter the values stored in string literals in Standard C.</P>
<P>Some earlier dialects have different rules for
<A HREF="express.html#Promoting" tppabs="http://ccs.ucsd.edu/c/express.html#Promoting">promoting</A> the
types <I>unsigned char, unsigned short,</I> and <I>unsigned bitfields.</I>
On most implementations, the difference is detectable only on a few
expressions where a negative value becomes a large positive value
of unsigned type. Add
<A HREF="express.html#Type Cast" tppabs="http://ccs.ucsd.edu/c/express.html#Type Cast">type casts</A>
to specify the types you require.</P>
<P>Earlier dialects convert lvalue expressions of type
<I>float</I> to <I>double,</I> in a
<A HREF="function.html#value context" tppabs="http://ccs.ucsd.edu/c/function.html#value context">value context</A>,
so all floating-point arithmetic
occurs only in type <I>double.</I> A program that depends on this
implicit increase in precision can behave differently in a Standard
C environment. Add type casts if you need the extra precision.</P>
<P>On some earlier dialects of C, shifting
an <I>int</I> or <I>unsigned int</I> value
<A HREF="express.html#Left Shift" tppabs="http://ccs.ucsd.edu/c/express.html#Left Shift">left</A> or
<A HREF="express.html#Right Shift" tppabs="http://ccs.ucsd.edu/c/express.html#Right Shift">right</A>
by a <I>long</I> or <I>unsigned long</I>
value first converts the value to be shifted to the type of the shift
count. In Standard C, the type of the shift count has no such effect.
Use a type cast if you need this behavior.</P>
<P>Some earlier dialects guarantee that the
<A HREF="preproc.html#if directive" tppabs="http://ccs.ucsd.edu/c/preproc.html#if directive"><I>if</I> directive</A>
performs arithmetic to the same precision as the
<A HREF="charset.html#target environment" tppabs="http://ccs.ucsd.edu/c/charset.html#target environment">target environment</A>.
(You can write an <I>if</I> directive that reveals properties of the
target environment.) Standard C makes no such guarantee.
Use the macros defined in
<A HREF="float.html" tppabs="http://ccs.ucsd.edu/c/float.html"><CODE>&lt;float.h&gt;</CODE></A> and
<A HREF="limits.html" tppabs="http://ccs.ucsd.edu/c/limits.html"><CODE>&lt;limits.h&gt;</CODE></A>
to test properties of the target environment.</P>
<P>Earlier dialects vary considerably
in the grouping of values within an object
<A HREF="declare.html#Object Initializers" tppabs="http://ccs.ucsd.edu/c/declare.html#Object Initializers">initializer</A>,
when you omit some (but not all) of the braces within the initializer.
Supply all braces for maximum clarity.</P>
<P>Earlier dialects convert the expression in any
<A HREF="function.html#Switch Statement" tppabs="http://ccs.ucsd.edu/c/function.html#Switch Statement"><I>switch</I> statement</A>
to type <I>int.</I> Standard C also performs comparisons
within a <I>switch</I> statement in other integer types. A
<A HREF="function.html#Case Label" tppabs="http://ccs.ucsd.edu/c/function.html#Case Label"><I>case</I> label</A>
expression that relies on being truncated when
<A HREF="express.html#Changing Representations" tppabs="http://ccs.ucsd.edu/c/express.html#Changing Representations">converted</A> to
<I>int,</I> in an earlier dialect, can behave differently in a Standard
C environment.</P>
<P>Some earlier preprocessing
<A HREF="preproc.html#Expanding Macros" tppabs="http://ccs.ucsd.edu/c/preproc.html#Expanding Macros">expands</A>
parameter names within string literals or character constants
that you write within a macro definition.
Standard C does not. Use the string literal
<A HREF="preproc.html#Creating String Literals" tppabs="http://ccs.ucsd.edu/c/preproc.html#Creating String Literals">creation</A>
operator <CODE>#</CODE>, along with
<A HREF="preproc.html#string-literal concatenation" tppabs="http://ccs.ucsd.edu/c/preproc.html#string-literal concatenation">string-literal
concatenation</A>, to replace this method.</P>
<P>Some earlier preprocessing concatenates preprocessor tokens
separated only by a comment within a macro definition. Standard C
does not. Use the
<A HREF="preproc.html#token concatenation" tppabs="http://ccs.ucsd.edu/c/preproc.html#token concatenation">token concatenation</A>
operator <CODE>##</CODE> to replace this method.</P>
<H2><A NAME="Newer Dialects">Newer Dialects</A></H2>
<P>Making standards for programming languages is an on-going activity.
As of this writing, the C Standard has been formally amended. A standard
for C++, which is closely related to C, is in the late stages of development.
One aspect of portability is writing code that is compatible with
these newer dialects, whether or not the code makes use of the newer
features.</P>
<P>Most of the features added with
<A HREF="lib_over.html#Amendment 1" tppabs="http://ccs.ucsd.edu/c/lib_over.html#Amendment 1">Amendment 1</A> are declared or
defined in three new headers --
<A HREF="iso646.html" tppabs="http://ccs.ucsd.edu/c/iso646.html"><CODE>&lt;iso646.h&gt;</CODE></A>,
<A HREF="wchar.html" tppabs="http://ccs.ucsd.edu/c/wchar.html"><CODE>&lt;wchar.h&gt;</CODE></A>, and
<A HREF="wctype.html" tppabs="http://ccs.ucsd.edu/c/wctype.html"><CODE>&lt;wctype.h&gt;</CODE></A>.
A few take the form of capabilities added to
the functions declared in
<A HREF="stdio.html" tppabs="http://ccs.ucsd.edu/c/stdio.html"><CODE>&lt;stdio.h&gt;</CODE></A>.
While not strictly necessary,
it is best to avoid using any of the names declared or defined in
these new headers.</P>
<P>Maintaining compatibility with C++ takes considerably more work.
It can be useful, however, to write in a common dialect called
<B><A NAME="typesafe C">typesafe C</A></B>
Here is a brief summary of the added constraints:</P>
<P>Avoid using any C++ keywords. As of this writing, the list includes:</P>
<PRE>
and and_eq asm bitand bitor
bool catch class compl delete
explicit false friend inline mutable
namespace new not not_eq operator
or or_eq private protected public
template this throw true try
typeid typename using virtual wchar_t
xor xor_eq const_cast dynamic_cast
reinterpret_cast static_cast</PRE>
<P>Write
<A HREF="function.html#function prototypes" tppabs="http://ccs.ucsd.edu/c/function.html#function prototypes">function prototypes</A>
for all functions you call.</P>
<P>Define each
<A HREF="declare.html#Tags" tppabs="http://ccs.ucsd.edu/c/declare.html#Tags">tag</A> name also as a type, as in:</P>
<PRE>
typedef struct x x;</PRE>
<P>Assume each
<A HREF="types.html#Enumerations" tppabs="http://ccs.ucsd.edu/c/types.html#Enumerations">enumeration</A> type
is a distinct type that promotes to an integer type.
<A HREF="express.html#Type Cast" tppabs="http://ccs.ucsd.edu/c/express.html#Type Cast">Type cast</A>
an integer expression that you assign
to an object of enumeration type.</P>
<P>Write an explicit storage class for each constant object declaration
at <A HREF="declare.html#file-level declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#file-level declaration">file level</A>.</P>
<P>Do not write
<A HREF="declare.html#tentative declaration" tppabs="http://ccs.ucsd.edu/c/declare.html#tentative declaration">tentative
declarations</A>.</P>
<P>Do not apply the
<A HREF="express.html#sizeof operator" tppabs="http://ccs.ucsd.edu/c/express.html#sizeof operator"><I>sizeof</I></A> operator to an
<A HREF="express.html#rvalue expression" tppabs="http://ccs.ucsd.edu/c/express.html#rvalue expression">rvalue</A> operand.</P>
<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>