744 lines
39 KiB
HTML
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>
|
|
· <A HREF="#Translation-Time Issues">Translation-Time Issues</A>
|
|
· <A HREF="#Character-Set Issues">Character-Set Issues</A>
|
|
· <A HREF="#Representation Issues">Representation Issues</A>
|
|
· <A HREF="#Expression-Evaluation Issues">Expression-Evaluation Issues</A>
|
|
· <A HREF="#Library Issues">Library Issues</A>
|
|
· <A HREF="#Converting to Standard C">Converting to Standard C</A>
|
|
· <A HREF="#Function-Call Issues">Function-Call Issues</A>
|
|
· <A HREF="#Preprocessing Issues">Preprocessing Issues</A>
|
|
· <A HREF="#Library Issues">Library Issues</A>
|
|
· <A HREF="#Quiet Changes">Quiet Changes</A>
|
|
· <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><stdarg.h></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><stdio.h></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><float.h></CODE></A> and
|
|
<A HREF="limits.html" tppabs="http://ccs.ucsd.edu/c/limits.html"><CODE><limits.h></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><iso646.h></CODE></A>,
|
|
<A HREF="wchar.html" tppabs="http://ccs.ucsd.edu/c/wchar.html"><CODE><wchar.h></CODE></A>, and
|
|
<A HREF="wctype.html" tppabs="http://ccs.ucsd.edu/c/wctype.html"><CODE><wctype.h></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><stdio.h></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> © 1989-1996
|
|
by P.J. Plauger and Jim Brodie. All rights reserved.</I></P>
|
|
|
|
</BODY></HTML>
|