comp.lang.c Changes to Answers to Frequently Asked Questions (FAQ)

Discussion in 'C Programming' started by Steve Summit, Jul 4, 2004.

  1. Steve Summit

    Steve Summit Guest

    Archive-name: C-faq/diff
    Comp-lang-c-archive-name: C-FAQ-list.diff
    URL: http://www.eskimo.com/~scs/C-faq/top.html

    It's been a long time. Far too long, but that's water under the bridge.
    Thanks, all, for your patience.

    This article lists the many, many differences between the previous
    version of the comp.lang.c FAQ list (version 3.5, last modified
    February 7, 1999, last posted June 1, 2004) and this finally-new one.

    I have scoured my archives for every unacknowledged suggestion and
    promised improvement, so for once I can say: this update is mostly
    complete. At this point, if you've sent me a suggestion which I
    haven't acknowledged or which isn't reflected here, I guess it
    wouldn't hurt if you sent it again.

    This update has been so long delayed that some of its improvements
    (such as the "new" question 19.17c) are already mildly obsolete;
    they were made to my master manuscripts years ago but have, alas,
    never seen the light of day until now.

    Because of some overly ambitious formatting changes I've embarked on,
    the updated HTML version is *still* not quite ready. But the light
    at the end of the tunnel is in sight: that grandish unveiling will
    happen in the next month or so.

    I've categorized the diffs that follow into brand-new questions,
    significant changes, minor adjustments, and (sob!) retired questions.
    The notation is based on that of the standard `diff' program: `<'
    indicates old, changed, or deleted text; `>' indicates new text.
    (For my fellow packrats out there: don't worry, the deleted
    questions, and most of the other deleted text, will live on
    in the web version...)


    First, the new questions. (Some of these are migrated from the
    book-length version, but most of them are brand new.)

    ==========

    > 2.4b: Is there a good way of simulating OOP-style inheritance, or
    > other OOP features, in C?
    >
    > A: It's straightforward to implement simple "methods" by placing
    > function pointers in structures. You can make various clumsy,
    > brute-force attempts at inheritance using the preprocessor or by
    > having structures contain "base types" as initial subsets, but
    > it won't be perfect. There's obviously no operator overloading,
    > and overriding (i.e. of "methods" in "derived classes") would
    > have to be done by hand.
    >
    > Obviously, if you need "real" OOP, you'll want to use a language
    > that supports it, such as C++.


    ==========

    > 3.12a: What's the difference between ++i and i++?
    >
    > A: If your C book doesn't explain, get a better one. Briefly:
    > ++i adds one to the stored value of i and "returns" the new,
    > incremented value to the surrounding expression; i++ adds one
    > to i but returns the prior, unincremented value.


    ==========

    > 4.15: How do I convert an int to a char *? I tried a cast, but it's
    > not working.
    >
    > A: It depends on what you're trying to do. If you tried a cast
    > but it's not working, you're probably trying to convert an
    > integer to a string, in which case see question 13.1. If you're
    > trying to convert an integer to a character, see question 8.6.
    > If you're trying to set a pointer to point to a particular
    > memory address, see question 19.25.


    ==========

    > 7.7c: In a call to malloc(), what does an error like "Cannot convert
    > `void *' to `int *'" mean?
    >
    > A: It means you're using a C++ compiler instead of a C compiler.
    > See question 7.7.


    ==========

    > 7.11: How can I dynamically allocate arrays?
    >
    > A: See questions 6.14 and 6.16.


    ==========

    > 11.8b: If you can't modify string literals, why aren't they defined as
    > being arrays of const characters?
    >
    > A: One reason is that so very much code contains lines like
    >
    > char *p = "Hello, world!";
    >
    > which are not necessarily incorrect. These lines would suffer
    > the diagnostic messages, but it's really any later attempt to
    > modify what p points to which would be problems.
    >
    > See also question 1.32.


    ==========

    > 11.14b: So what could go wrong? Are there really any systems where
    > void main() doesn't work?
    >
    > A: It has been reported that programs using void main() and
    > compiled using BC++ 4.5 can crash. Some compilers (including
    > DEC C V4.1 and gcc with certain warnings enabled) will complain
    > about void main().


    ==========

    > 11.33b: What does it really mean for a program to be "legal" or "valid"
    > or "conforming"?
    >
    > A: Simply stated, the Standard talks about three kinds of
    > conformance: conforming programs, strictly conforming programs,
    > and conforming implementations.
    >
    > A "conforming program" is one that is accepted by a conforming
    > implementation.
    >
    > A "strictly conforming program" is one that uses the language
    > exactly as specified in the Standard, and that does not depend
    > on any implementation-defined, unspecified, or undefined
    > behavior.
    >
    > A "conforming implementation" is one that does everything the
    > Standard says it's supposed to.
    >
    > References: ISO Sec. ; Rationale Sec. 1.7.


    ==========

    > 12.1b: I have a simple little program that reads characters until EOF,
    > but how do I actually *enter* that "EOF" value from the
    > keyboard?
    >
    > A: It turns out that the value of EOF as seen within your C program
    > has essentially nothing to do with the keystroke combination you
    > might use to signal end-of-file from the keyboard. Depending on
    > your operating system, you indicate end-of-file from the
    > keyboard using various keystroke combinations, usually either
    > control-D or control-Z.


    ==========

    > 12.12b: Why *does* the call
    >
    > char s[30];
    > scanf("%s", s);
    >
    > work (without the &)?
    >
    > A: You always need a *pointer*; you don't necessarily need an
    > explicit &. When you pass an array to scanf(), you do not need
    > the &, because arrays are always passed to functions as
    > pointers, whether you use & or not. See questions 6.3 and 6.4.


    ==========

    > 12.26b: If fflush() won't work, what can I use to flush input?
    >
    > A: It depends on what you're trying to do. If you're trying to get
    > rid of an unread newline or other unexpected input after calling
    > scanf() (see questions 12.18a-12.19), you really need to rewrite
    > or replace the call to scanf() (see question 12.20).
    > Alternatively, you can consume the rest of a partially-read line
    > with a simple code fragment like
    >
    > while((c = getchar()) != '\n' && c != EOF)
    > /* discard */ ;
    >
    > (You may also be able to use the curses flushinp() function.)


    ==========

    > 12.27: fopen() is failing for certain pathnames.
    >
    > A: See questions 19.17 and 19.17b.


    ==========

    > 13.29: My compiler is complaining that printf is undefined!
    > How can this be?
    >
    > A: Allegedly, there are C compilers for Microsoft Windows which do
    > not support printf(). It may be possible to convince such a
    > compiler that what you are writing is a "console application"
    > meaning that it will open a "console window" in which printf()
    > is supported.


    ==========

    > 17.4b: I've seen function declarations that look like this:
    >
    > extern int func __((int, int));
    >
    > What are those extra parentheses and underscores for?
    >
    > A: They're part of a trick which allows the prototype part of the
    > function declaration to be turned off for a pre-ANSI compiler.
    > Somewhere else is a conditional definition of the __ macro like
    > this:
    >
    > #ifdef __STDC__
    > #define __(proto) proto
    > #else
    > #define __(proto) ()
    > #endif
    >
    > The extra parentheses in the invocation
    >
    > extern int func __((int, int));
    >
    > are required so that the entire prototype list (perhaps
    > containing many commas) is treated as the single argument
    > expected by the macro.


    ==========

    > 18.9b: Where can I find some good code examples to study and learn
    > from?
    >
    > A: Here are a couple of links to explore:
    >
    > ftp://garbo.uwasa.fi/pc/c-lang/00index.txt
    >
    > http://www.eskimo.com/~scs/src/
    >
    > (Beware, though, that there is all too much truly bletcherous
    > code out there, too. Don't "learn" from bad code that it's the
    > best anyone can do; you can do better.) See also questions
    > 18.9, 18.13, 18.15c, and 18.16.


    ==========

    > 19.9b: How can I access an I/O board directly?
    >
    > A: In general, there are two ways to do this: use system-specific
    > functions such as "inport" and "outport" (if the device is
    > accessed via an "I/O port"), or use contrived pointer variables
    > to access "memory-mapped I/O" device locations. See question
    > 19.25.


    ==========

    > 19.10b: How can I display GIF and JPEG images?
    >
    > A: It will depend on your display environment, which may already
    > provide these functions. Reference JPEG software is at
    > http://www.ijg.org/files/ .


    ==========

    > 19.17b: fopen() isn't letting me open files like "$HOME/.profile" and
    > "~/.myrcfile".
    >
    > A: Under Unix, at least, environment variables like $HOME, along
    > with the home-directory notation involving the ~ character, are
    > expanded by the shell, and there's no mechanism to perform these
    > expansions automatically when you call fopen().


    ==========

    > 19.17c: How can I suppress the dreaded MS-DOS "Abort, Retry, Ignore?"
    > message?
    >
    > A: Among other things, you need to intercept the DOS Critical Error
    > Interrupt, interrupt 24H. See the comp.os.msdos.programmer FAQ
    > list for more details.


    ==========

    > 19.40d: What are "near" and "far" pointers?
    >
    > A: These days, they're pretty much obsolete; they're definitely
    > system-specific. If you really need to know, see a DOS- or
    > Windows-specific programming reference.


    ==========

    > 20.9b: How do I swap bytes?
    >
    > A: V7 Unix had a swab() function, but it seems to have been
    > forgotten.
    >
    > A problem with explicit byte-swapping code is that you have
    > to decide whether to call it or not; see question 20.9 above.
    > A better solution is to use functions (such as the BSD
    > networking ntohs() et al.) which convert between the known byte
    > order of the data and the (unknown) byte order of the machine,
    > and to arrange for these functions to be no-ops on those
    > machines which already match the desired byte order.
    >
    > If you do have to write your own byte-swapping code, the two
    > obvious approaches are again to use pointers or unions, as in
    > question 20.9.
    >
    > References: PCS Sec. 11 p. 179.


    ====================


    Next, here are the significant changes.

    ==========

    [Q1.1 How should I decide which integer type to use?]

    If for some reason you need to declare something with an
    *exact* size... be sure to encapsulate the choice behind
    < an appropriate typedef.
    ---
    > an appropriate typedef, such as those in C99's <inttypes.h>.


    > If you need to manipulate huge values, larger than the
    > guaranteed range of C's built-in types, see question 18.15d.


    ==========

    [Q1.4 What should the 64-bit type be on a machine that can support it?]

    < A: The forthcoming revision to the C Standard (C9X) specifies type
    < long long as effectively being at least 64 bits, and this type
    < has been implemented by a number of compilers for some time.
    < (Others have implemented extensions such as __longlong.)
    < On the other hand, there's no theoretical reason why a compiler
    < couldn't implement type short int as 16, int as 32, and long int
    < as 64 bits, and some compilers do indeed choose this
    < arrangement.
    ---
    > A: The new C99 Standard specifies type long long as effectively
    > being at least 64 bits, and this type has been implemented by a
    > number of compilers for some time. (Others have implemented
    > extensions such as __longlong.) On the other hand, it's also
    > appropriate to implement type short int as 16, int as 32, and
    > long int as 64 bits, and some compilers do.


    ==========

    [Q1.7 What's the best way to declare and define global variables...]

    A: First, though there can be many "declarations" (and in many
    < translation units) of a single "global" (strictly speaking,
    < "external") variable or function, there must be exactly one
    < "definition". (The definition is the declaration that actually
    < allocates space, and provides an initialization value, if any.)
    ---
    > translation units) of a single global variable or function,
    > there must be exactly one "definition", where the definition is
    > the declaration that actually allocates space, and provides an
    > initialization value, if any.


    ==========

    (Unix compilers and linkers typically use a "common model" which
    allows multiple definitions, as long as at most one is
    initialized; this behavior is mentioned as a "common extension"
    < by the ANSI Standard, no pun intended. A few very odd systems
    < may require an explicit initializer to distinguish a definition
    < from an external declaration.)
    ---
    > by the ANSI Standard, no pun intended.)


    ==========

    [Q1.25 My compiler is complaining about an invalid redeclaration...]

    < A: Functions which are called without a declaration in scope
    < (perhaps because the first call precedes the function's
    < definition) are assumed to be declared as returning int (and
    without any argument type information), leading to discrepancies
    < if the function is later declared or defined otherwise. Non-int
    < functions must be declared before they are called.
    ---
    > A: Functions which are called without a declaration in scope,
    > perhaps because the first call precedes the function's
    > definition, are assumed to be declared as returning int (and

    without any argument type information), leading to discrepancies
    > if the function is later declared or defined otherwise. All
    > functions should be (and non-int functions must be) declared
    > before they are called.


    ==========

    [Q1.30 What am I allowed to assume about the initial values...]

    > These rules do apply to arrays and structures (termed
    > "aggregates"); arrays and structures are considered "variables"
    > as far as initialization is concerned.


    ==========

    [Q1.31 This code, straight out of a book, isn't compiling]

    < A: Perhaps you have a pre-ANSI compiler, which doesn't allow
    < initialization of "automatic aggregates" (i.e. non-static
    < local arrays, structures, and unions). (As a workaround, and
    < depending on how the variable a is used, you may be able to make
    < it global or static, or replace it with a pointer, or initialize
    < it by hand with strcpy() when f() is called.)
    ---
    > A: Perhaps you have an old, pre-ANSI compiler, which doesn't allow
    > initialization of "automatic aggregates" (i.e. non-static local
    > arrays, structures, or unions).


    ==========

    [Q1.34 I finally figured out the syntax for... pointers to functions...]

    < An explicit declaration for the function is normally needed,
    < since implicit external function declaration does not happen in
    < this case (because the function name in the initialization is
    < not part of a function call).
    ---
    > A prior, explicit declaration for the function (perhaps in a
    > header file) is normally needed. The implicit external function
    > declaration that can occur when a function is called does not
    > help when a function name's only use is for its value.


    ==========

    [Q2.4 How can I implement opaque (abstract) data types in C?]

    A: One good way is for clients to use structure pointers (perhaps
    additionally hidden behind typedefs) which point to structure
    > types which are not publicly defined. It's legal to declare
    > and use "anonymous" structure pointers (that is, pointers to
    > structures of incomplete type), as long as no attempt is made to
    > access the members -- which of course is exactly the point of an
    > opaque type.


    ==========

    [Q2.6 I came across some code that declared a structure like this...]

    these "chummy" structures must be used with care, since the
    programmer knows more about their size than the compiler does.
    < (In particular, they can generally only be manipulated via
    < pointers.)

    < C9X will introduce the concept of a "flexible array member",
    < which will allow the size of an array to be omitted if it is
    < the last member in a structure, thus providing a well-defined
    < solution.
    ---
    > C99 introduces the concept of a "flexible array member", which
    > allows the size of an array to be omitted if it is the last
    > member in a structure, thus providing a well-defined solution.


    ==========

    [Q2.10 How can I pass constant... structure arguments?]

    < A: As of this writing, C has no way of generating anonymous
    < structure values. You will have to use a temporary structure
    < variable or a little structure-building function.
    ---
    > A: Traditional C had no way of generating anonymous structure
    > values; you had to use a temporary structure variable or a
    > little structure-building function.


    < The C9X Standard will introduce "compound literals"; one form of
    < compound literal will allow structure constants. For example,
    < to pass a constant coordinate pair to a plotpoint() function
    < which expects a struct point, you will be able to call
    ---
    > C99 introduces "compound literals", one form of which provides
    > for structure constants. For example, to pass a constant
    > coordinate pair to a hypothetical plotpoint() function which
    > expects a struct point, you can call


    < Combined with "designated initializers" (another C9X feature),
    < it will also be possible to specify member values by name:
    ---
    > Combined with "designated initializers" (another C99 feature),
    > it is also possible to specify member values by name:


    ==========

    2.12: My compiler is leaving holes in structures, which is wasting
    < space and preventing "binary" I/O to external data files. Can I
    < turn off the padding, or otherwise control the alignment of
    ---
    > space and preventing "binary" I/O to external data files. Why?
    > Can I turn this off, or otherwise control the alignment of


    < A: Your compiler may provide an extension to give you this control
    < (perhaps a #pragma; see question 11.20), but there is no
    < standard method.
    ---
    > A: Those "holes" provide "padding", which may be needed in order to
    > preserve the "alignment" of later fields of the structure. For
    > efficient access, most processors prefer (or require) that
    > multibyte objects (e.g. structure members of any type larger
    > than char) not sit at arbitrary memory addresses, but rather at
    > addresses which are multiples of 2 or 4 or the object size.
    >
    > Your compiler may provide an extension to give you explicit
    > control over struct alignment (perhaps involving a #pragma; see
    > question 11.20), but there is no standard method.


    ==========

    [Q2.14 How can I determine the byte offset of a field within a structure?]

    < A: ANSI C defines the offsetof() macro, which should be used if
    < available; see <stddef.h>. If you don't have it, one possible
    < implementation is
    ---
    > A: ANSI C defines the offsetof() macro in <stddef.h>, which lets
    > you compute the offset of field f in struct s as
    > offsetof(struct s, f). If for some reason you have to code this
    > sort of thing yourself, one possibility is


    ==========

    [2.15 How can I access structure fields by name at run time?]

    < A: Build a table of names and offsets, using the offsetof() macro.
    < The offset of field b in struct a is
    <
    < offsetb = offsetof(struct a, b)
    <
    < If structp is a pointer to an instance of this structure, and
    < field b is an int (with offset as computed above), b's value can
    < be set indirectly with
    ---
    > A: Keep track of the field offsets as computed using the offsetof()
    > macro (see question 2.14). If structp is a pointer to an
    > instance of the structure, and field f is an int having offset
    > offsetf, f's value can be set indirectly with


    ==========

    [Q2.20 Can I initialize unions?]

    < A: The current C Standard allows an initializer for the first-named
    < member of a union. C9X will introduce "designated initializers"
    < which can be used to initialize any member.
    ---
    > A: In the original ANSI C, an initializer was allowed only for the
    > first-named member of a union. C99 introduces "designated
    > initializers" which can be used to initialize any member.


    ==========

    [Q3.2 Under my compiler... Regardless of the order of evaluation...]

    example, the compiler chose to multiply the previous value by
    < itself and to perform both increments afterwards.
    ---
    > itself and to perform both increments later.


    [Q3.8 How can I understand these complex expressions?]

    The second sentence can be difficult to understand. It says
    that if an object is written to within a full expression, any
    < and all accesses to it within the same expression must be for
    < the purposes of computing the value to be written. This rule
    effectively constrains legal expressions to those in which the
    accesses demonstrably precede the modification.
    ---
    > and all accesses to it within the same expression must be
    > directly involved in the computation of the value to be written.

    This rule effectively constrains legal expressions to those in
    > which the accesses demonstrably precede the modification. For
    > example, i = i + 1 is legal, but not a = i++ (see question
    > 3.1).


    ==========

    [3.9 So... we don't know which..., but i does get incremented..., right?]

    < A: *No*. Once an expression or program becomes undefined, *all*
    ---
    > A: Not necessarily! Once an expression or program becomes

    undefined, *all* aspects of it become undefined.

    ==========

    [Q4.2 I'm trying to declare a pointer and allocate some space for it...]

    < A: The pointer you declared is p, not *p. To make a pointer point
    < somewhere, you just use the name of the pointer:
    ---
    > A: The pointer you declared is p, not *p. When you're manipulating
    > the pointer itself (for example when you're setting it to make
    > it point somewhere), you just use the name of the pointer:


    ==========

    [4.3 Does *p++ increment p, or what it points to?]

    < A: Postfix ++ essentially has higher precedence than the prefix
    ---
    > A: The postfix ++ and -- operators essentially have higher

    precedence than the prefix unary operators.

    ==========

    [Q4.10 ...How can I pass a constant by reference?]

    < A: You can't do this directly. You will have to declare
    ---
    > A: In C99, you can use a "compound literal":
    >
    > f((int[]){5});
    >
    > Prior to C99, you couldn't do this directly; you had to declare

    a temporary variable, and then pass its address to the function:

    ==========

    [Q5.6 If NULL were defined as follows...]

    > At any rate, ANSI function prototypes ensure that most (though
    > not quite all; see question 5.2) pointer arguments are converted
    > correctly when passed as function arguments, so the question is
    > largely moot.


    ==========

    5.20: What does a run-time "null pointer assignment" error mean?
    < How can I track it down?

    < A debugger may let you set a data watchpoint on location 0.
    < Alternatively, you could write a bit of code to stash away a
    < copy of 20 or so bytes from location 0, and periodically check
    < that the memory at location 0 hasn't changed. See also question
    < 16.8.

    ==========

    [Q6.15 How can I declare local arrays of a size matching a passed-in array?]

    < A: Until recently, you couldn't. Array dimensions in C
    < traditionally had to be compile-time constants. C9X will
    < introduce variable-length arrays (VLA's) which will solve this
    ---
    > A: Until recently, you couldn't; array dimensions in C
    > traditionally had to be compile-time constants. However, C99
    > introduces variable-length arrays (VLA's) which solve this

    problem; local arrays may have sizes set by variables or other
    expressions, perhaps involving function parameters.

    ==========

    [Q6.16 How can I dynamically allocate a multidimensional array?]

    > You can also use sizeof(*array1) and sizeof(**array1)
    > instead of sizeof(int *) and sizeof(int).)


    ==========

    [Q6.19 How do I write functions which accept two-dimensional arrays...]

    < C9X will allow variable-length arrays, and once compilers which
    < accept C9X's extensions become widespread, this will probably
    ---
    > C99 allows variable-length arrays, and once compilers which
    > accept C99's extensions become widespread, VLA's will probably

    become the preferred solution.

    ==========

    [Q7.27 So can I query the malloc package to find out how big...]

    > (Some compilers provide nonstandard extensions.)


    ==========

    [Q7.32 What is alloca() and why is its use discouraged?]

    > Now that C99 supports variable-length arrays (VLA's),
    > they can be used to more cleanly accomplish most of the
    > tasks which alloca() used to be put to.


    ==========

    [Q8.6 How can I get the numeric (character set) value corresponding to...]

    > To convert back and forth between the digit characters and the
    > corresponding integers in the range 0-9, add or subtract the
    > constant '0' (that is, the character value '0').


    ==========

    [Q10.7 Is it acceptable for one header file to #include another?]

    the prestigious Indian Hill Style Guide (see question 17.9)
    disparages them; they can make it harder to find relevant
    definitions; they can lead to multiple-definition errors if a file
    < is #included twice;
    ---
    > is #included twice; they can lead to increased compilation time;

    and they make manual Makefile maintenance very difficult.

    ==========

    < 10.11: I seem to be missing the system header file <sgtty.h>.
    < Can someone send me a copy?
    ---
    > 10.11: I'm compiling a program, and I seem to be missing one of the
    > header files it requires. Can someone send me a copy?


    > A: There are several situations, depending on what sort of header
    > file it is that's "missing".
    >
    > If the missing header file is a standard one, there's a problem
    > with your compiler. You'll need to contact your vendor, or
    > someone knowledgeable about your particular compiler, for help.
    >
    > The situation is more complicated in the case of nonstandard
    > headers. Some are completely system- or compiler-specific.
    > Some are completely unnecessary, and should be replaced by their
    > Standard equivalents. (For example, instead of <malloc.h>, use
    > <stdlib.h>.) Other headers, such as those associated with
    > popular add-on libraries, may be reasonably portable.


    Standard headers exist in part so that definitions appropriate
    to your compiler, operating system, and processor can be
    supplied. You cannot just pick up a copy of someone else's
    header file and expect it to work, unless that person is using
    < exactly the same environment. Ask your compiler vendor why the
    < file was not provided (or to send a replacement copy).
    ---
    > exactly the same environment. You may actually have a
    > portability problem (see section 19), or a compiler problem.
    > Otherwise, see question 18.16.


    ==========

    [Q10.26 How can I write a macro which takes a variable number of arguments?]

    < C9X will introduce formal support for function-like macros with
    < variable-length argument lists. The notation ... will appear at
    ---
    > C99 introduces formal support for function-like macros with
    > variable-length argument lists. The notation ... can appear at


    < definition will be replaced by the variable arguments during
    ---
    > definition is replaced by the variable arguments during


    ==========

    [Q11.1 What is the "ANSI C Standard?"]

    < More recently, the Standard has been adopted as an international
    < standard, ISO/IEC 9899:1990, and this ISO Standard replaces the
    < earlier X3.159 even within the United States (where it is known
    ---
    > A year or so later, the Standard was adopted as an international
    > standard, ISO/IEC 9899:1990, and this ISO Standard replaced the
    > earlier X3.159 even within the United States (where it was known


    < As of this writing, a complete revision of the Standard is in
    < its final stages. The new Standard is nicknamed "C9X" on the
    < assumption that it will be finished by the end of 1999. (Many
    < of this article's answers have been updated to reflect new C9X
    < features.)
    ---
    > Most recently, a major revision of the Standard, "C99", has been
    > completed and adopted.


    < The original ANSI Standard included a "Rationale," explaining
    < many of its decisions, and discussing a number of subtle points,
    < including several of those covered here. (The Rationale was
    < "not part of ANSI Standard X3.159-1989, but... included for
    < information only," and is not included with the ISO Standard.
    < A new one is being prepared for C9X.)
    ---
    > Several versions of the Standard, including C99 and the original
    > ANSI Standard, have included a "Rationale," explaining many of
    > its decisions, and discussing a number of subtle points,
    > including several of those covered here.


    ==========

    [Q11.2 How can I get a copy of the Standard?]

    < Note that ANSI derives revenues to support its operations
    < from the sale of printed standards, so electronic copies
    < are *not* available.
    ---
    > An electronic (PDF) copy is available on-line, for US$18,
    > from www.ansi.org.


    < The last time I checked, the cost was $130.00 from ANSI or
    < $400.50 from Global. Copies of the original X3.159 (including
    < the Rationale) may still be available at $205.00 from ANSI or
    < $162.50 from Global.

    < In the U.S., it may be possible to get a copy of the original
    < ANSI X3.159 (including the Rationale) as "FIPS PUB 160" from
    <
    < National Technical Information Service (NTIS)
    < U.S. Department of Commerce
    < Springfield, VA 22161
    < 703 487 4650

    ==========

    [Q11.10 Why can't I pass a char ** to a function which expects...]

    < You must use explicit casts (e.g. (const char **) in this case)
    < when assigning (or passing) pointers which have qualifier
    < mismatches at other than the first level of indirection.
    ---
    > If you must assign or pass pointers which have qualifier
    > mismatches at other than the first level of indirection, you
    > must use explicit casts (e.g. (const char **) in this case),
    > although as always, the need for such a cast may indicate a
    > deeper problem which the cast doesn't really fix.


    ==========

    < 11.27: Why does the ANSI Standard not guarantee more than six case-
    < insensitive characters of external identifier significance?
    ---
    > 11.27: Why does the ANSI Standard place limits on the length and case-
    > significance of external identifiers?


    The limitation is only that identifiers be *significant*
    < in the first six characters, not that they be restricted to
    < six characters in length. This limitation is marked in the
    < Standard as "obsolescent", and will be removed in C9X.
    ---
    > in some initial sequence of characters, not that they be
    > restricted to that many characters in total length.
    > (The limitation was to six characters in the original
    > ANSI Standard, but has been relaxed to 31 in C99.)


    ==========

    [Q11.33 ...implementation-defined, unspecified, and undefined behavior.]

    > (A fourth defined class of not-quite-precisely-defined behavior,
    > without the same stigma attached to it, is "locale-specific".)


    ==========

    [Q12.2 Why does the code... copy the last line twice?]

    Usually, you should just check the return value of
    < the input routine (in this case, fgets() will return NULL on end-
    < of-file); often, you don't need to use feof() at all.
    ---
    > the input routine -- fgets(), for example, returns NULL on end-
    > of-file. In virtually all cases, there's no need to use feof()
    > at all.


    ==========

    [Q12.21 How can I tell how much... buffer space... for a... sprintf call?]

    < The "obvious" solution to the overflow problem is a length-
    < limited version of sprintf(), namely snprintf(). It would be
    < used like this:
    ---
    > To avoid the overflow problem, you can use a length-limited
    > version of sprintf(), namely snprintf(). It is used like this:


    < It will be standardized in C9X.
    ---
    > It has finally been standardized in C99.


    < When the C9X snprintf() arrives, it will also be possible to use
    < it to predict the size required for an arbitrary sprintf() call.
    < C9X snprintf() will return the number of characters it would
    < have placed in the buffer, not just how many it did place.
    < Furthermore, it may be called with a buffer size of 0 and a
    < null pointer as the destination buffer. Therefore, the call
    ---
    > As an extra, added bonus, the C99 snprintf() provides a way
    > to predict the size required for an arbitrary sprintf() call.
    > C99's snprintf() returns the number of characters it would have
    > placed in the buffer, and it may be called with a buffer size
    > of 0. Therefore, the call


    < will compute the number of characters required for the fully-
    ---
    > predicts the number of characters required for the fully-


    > Yet another option is the (nonstandard) asprintf() function,
    > present in various C libraries including bsd's and GNU's, which
    > formats to (and returns a pointer to) a malloc'ed buffer, like
    > this:
    >
    > char *buf;
    > asprintf(&buf, "%d = %s", 42, "forty-two");
    > /* now buf points to malloc'ed space containing formatted string */


    ==========

    [Q12.23 Why does everyone say not to use gets()?]

    A: Unlike fgets(), gets() cannot be told the size of the buffer
    it's to read into, so it cannot be prevented from overflowing
    < that buffer. As a general rule, always use fgets().
    ---
    > that buffer. The Standard fgets() function is a vast
    > improvement over gets(), although it's not perfect, either.
    > (If long lines are a real possibility, their proper handling
    > must be carefully considered.)


    ==========

    < 12.26: How can I flush pending input so that a user's typeahead isn't
    ---
    > 12.26b: If fflush() won't work, what can I use to flush input?


    There is no standard way to discard unread characters from a
    stdio input stream, nor would such a way necessarily be
    sufficient, since unread characters can also accumulate in
    < other, OS-level input buffers. You may be able to read and
    < discard characters until \n, or use the curses flushinp()
    < function, or use some system-specific technique. See also
    < questions 19.1 and 19.2.
    ---
    > other, OS-level input buffers. If you're trying to actively
    > discard typed-ahead input (perhaps in anticipation of issuing a
    > critical prompt), you'll have to use a system-specific
    > technique; see questions 19.1 and 19.2.


    ==========

    [Q12.30 I'm trying to update a file in place...]

    writing in the read/write "+" modes. Also, remember that you
    can only overwrite characters with the same number of
    replacement characters, and that overwriting in text mode may
    < truncate the file at that point. See also question 19.14.
    ---
    > truncate the file at that point, and that you may have to
    > preserve line lengths. See also question 19.14.


    ==========

    [Q12.34 Once I've used freopen(), how can I get the original stdout... back?]

    < It is barely possible to save away information about a stream
    < before calling freopen(), such that the original stream can
    < later be restored, but the methods involve system-specific calls
    < such as dup(), or copying or inspecting the contents of a FILE
    < structure, which is exceedingly nonportable and unreliable.
    ---
    > It may be possible, in a nonportable way, to save away
    > information about a stream before calling freopen(), such that
    > the original stream can later be restored. One way is to use a
    > system-specific call such as dup() or dup2(), if available.
    > Another is to copy or inspect the contents of the FILE
    > structure, but this is exceedingly nonportable and unreliable.


    ==========

    12.36b: How can I arrange to have output go two places at once,
    e.g. to the screen and to a file?

    > Here is a simple example:
    >
    > #include <stdio.h>
    > #include <stdarg.h>
    >
    > void f2printf(FILE *fp1, FILE *fp2, char *fmt, ...)
    > {
    > va_list argp;
    > va_start(argp, fmt); vfprintf(fp1, fmt, argp); va_end(argp);
    > va_start(argp, fmt); vfprintf(fp2, fmt, argp); va_end(argp);
    > }
    >
    > where f2printf() is just like fprintf() except that you give it
    > two file pointers and it prints to both of them.


    ==========

    [Q13.2 Why does strncpy() not always place a '\0' terminator...]

    You can get around the problem by using strncat() instead
    of strncpy(): if the destination string starts out empty
    > (that is, if you do *dest = '\0' first), strncat()

    does what you probably wanted strncpy() to do.

    ==========

    [Q13.12 How can I get the current date or time of day in a C program?]

    < printf("It's %.24s.\n", ctime(&now));
    ---
    > printf("It's %s", ctime(&now));


    > If you need control over the format, use strftime().
    > If you need sub-second resolution, see question 19.37.


    ==========

    [Q13.14 How can I add N days to a date?]

    A: The ANSI/ISO Standard C mktime() and difftime() functions
    < provide some support for both problems.
    ---
    > provide some (limited) support for both problems.


    < These solutions are only guaranteed to work correctly
    ---
    > However, these solutions are guaranteed to work correctly only

    for dates in the range which can be represented as time_t's.

    > (For conservatively-sized time_t, that range is often -- but not
    > always -- from 1970 to approximately 2037; note however that
    > there are time_t representations other than as specified by Unix
    > and Posix.)


    Another approach to both problems,
    > which will work over a much wider range of dates,

    is to use "Julian day numbers".

    ==========

    [Q13.15 I need a random number generator.]

    If you do find yourself needing to implement your own random
    number generator, there is plenty of literature out there; see
    < the References. There are also any number of packages on the
    < net: look for r250, RANLIB, and FSULTRA (see question 18.16).
    ---
    > the References below or the sci.math.num-analysis FAQ list.
    > There are also any number of packages on the net: old standbys
    > are r250, RANLIB, and FSULTRA (see question 18.16), and there is
    > much recent work by Marsaglia, and Matumoto and Nishimura (the
    > "Mersenne Twister"), and some code collected by Don Knuth on his
    > web pages.


    ==========

    [Q13.17 Each time I run my program, I get the same sequence of numbers...]

    A: You can call srand() to seed the pseudo-random number generator
    < with a truly random initial value. Popular seed values are the
    < time of day, or the elapsed time before the user presses a key
    < (although keypress times are hard to determine portably;
    ---
    > with a truly random (or at least variable) initial value, such
    > as the time of day. Here is a simple example:
    >
    > #include <stdlib.h>
    > #include <time.h>
    >
    > srand((unsigned int)time((time_t *)NULL));
    >
    > (Unfortunately, this code isn't perfect -- among other things,
    > the time_t returned by time() might be a floating-point type,
    > hence not portably convertible to unsigned int without the
    > possibility of overflow.


    ==========

    [Q14.1 When I set a float... 3.1, why is printf printing it as 3.0999999?]

    A: Most computers use base 2 for floating-point numbers as well as
    < for integers. In base 2, one divided by ten is an infinitely-
    < repeating fraction (0.0001100110011...), so fractions such as
    < 3.1 (which look like they can be exactly represented in decimal)
    ---
    > for integers. Although 0.1 is a nice, polite-looking fraction
    > in base 10, its base-2 representation is an infinitely-repeating
    > fraction (0.0001100110011...), so exact decimal fractions such as 3.1

    cannot be represented exactly in binary.

    [Q14.3 ...I keep getting "undefined: sin" compilation errors.]

    A: Make sure you're actually linking with the math library. For
    < instance, under Unix, you usually need to use the -lm option, at
    ---
    > instance, due to a longstanding bug in Unix and Linux systems,
    > you usually need to use an explicit -lm flag, at the *end* of

    the command line, when compiling/linking.

    ==========

    [Q14.5 What's a good way to check for "close enough" floating-point equality?]

    use something like

    #include <math.h>
    if(fabs(a - b) <= epsilon * fabs(a))

    < for some suitably-chosen degree of closeness epsilon (as long as
    < a is nonzero!).
    ---
    > where epsilon is a value chosen to set the degree of "closeness"
    > (and where you know that a will not be zero).


    ==========

    [Q14.8 The predefined constant M_PI seems to be missing...]
    machine's copy of <math.h>.

    If you need pi, you'll have to define it yourself, or compute it
    < with 4*atan(1.0).
    ---
    > with 4*atan(1.0) or acos(-1.0).


    ==========

    [Q14.9 How do I test for IEEE NaN and other special values?]

    < C9X will provide isnan(), fpclassify(), and several other
    ---
    > C99 provides isnan(), fpclassify(), and several other

    classification routines.

    ==========

    [Q14.11 What's a good way to implement complex numbers in C?]

    < C9X will support complex as a standard type.
    ---
    > C99 supports complex as a standard type.


    ==========

    [Q15.6 How can I write a function analogous to scanf()...]

    < A: C9X will support vscanf(), vfscanf(), and vsscanf().
    < (Until then, you may be on your own.)
    ---
    > A: C99 (but *not* any earlier C Standard) supports vscanf(),
    > vfscanf(), and vsscanf().


    ==========

    [Q16.1b I'm getting baffling syntax errors which make no sense at all...]

    < A: Check for unclosed comments or mismatched #if/#ifdef/#ifndef/
    < #else/#endif directives; remember to check header files, too.
    ---
    > A: Check for unclosed comments, mismatched #if/#ifdef/#ifndef/
    > #else/#endif directives, and perhaps unclosed quotes; remember

    to check header files, too.

    [Section 18. Tools and Resources]

    > [NOTE: Much of the information in this section is fairly old and may be
    > out-of-date, especially the URLs of various allegedly publicly-available
    > packages. Caveat lector.]


    ==========

    [Q18.1 I need...]

    tools to compute code ccount, Metre, lcount, or csize,
    < metrics or see URL http://www.qucis.queensu.ca/
    < Software-Engineering/Cmetrics.html ;
    ---
    > tools to compute code ccount, Metre, lcount, or csize;

    metrics there is also a package sold by
    McCabe and Associates

    ==========

    [Q18.2 How can I track down these pesky malloc problems?]

    < MEMDEBUG from ftp.crpht.lu in pub/sources/memdebug .
    ---
    > MEMDEBUG from ftp.crpht.lu in pub/sources/memdebug ; and
    > Electric Fence.


    < Bounds-Checker for DOS, from Nu-Mega Technologies,
    < P.O. Box 7780, Nashua, NH 03060-7780, USA, 603-889-2386.

    CodeCenter (formerly Saber-C) from Centerline Software,
    < 10 Fawcett Street, Cambridge, MA 02138, USA, 617-498-3000.
    ---
    > (http://www.centerline.com/).


    < Insight, from ParaSoft Corporation, 2500 E. Foothill
    < Blvd., Pasadena, CA 91107, USA, 818-792-9941,
    < .
    ---
    > Insight (now Insure?), from ParaSoft Corporation
    > (http://www.parasoft.com/).


    < Purify, from Pure Software, 1309 S. Mary Ave., Sunnyvale,
    < CA 94087, USA, 800-224-7873, http://www.pure.com ,
    < .
    < (I believe Pure was recently acquired by Rational.)
    ---
    > Purify, from Rational Software (http://www-
    > 306.ibm.com/software/rational/, formerly Pure Software,
    > now part of IBM).


    < Final Exam Memory Advisor, from PLATINUM Technology
    < (formerly Sentinel from AIB Software), 1815 South Meyers
    < Rd., Oakbrook Terrace, IL 60181, USA, 630-620-5000,
    < 800-442-6861, , www.platinum.com .

    < ZeroFault, from The Kernel Group, 1250 Capital of Texas
    < Highway South, Building Three, Suite 601, Austin,
    < TX 78746, 512-433-3333, http://www.tkg.com, .
    ---
    > ZeroFault, from The ZeroFault Group,
    > http://www.zerofault.com/.


    ==========

    [Q18.3 What's a free or cheap C compiler I can use?]

    < compiler, or gcc. It is available by anonymous ftp from
    < prep.ai.mit.edu in directory pub/gnu, or at several other FSF
    < archive sites.
    ---
    > compiler, or gcc; see the gcc home page at http://gcc.gnu.org/.


    < There are currently no viable shareware compilers for the
    < Macintosh.
    ---
    > As far as I know, there
    > are versions of gcc for Macs and Windows machines, too.


    < There is a shareware compiler called PCC, available as
    < PCC12C.ZIP .

    < Another recently-developed compiler is lcc, available for
    < anonymous ftp from ftp.cs.princeton.edu in pub/lcc/.
    ---
    > Another popular compiler is lcc, described at
    > http://www.cs.virginia.edu/~lcc-win32/ and
    > http://www.cs.princeton.edu/software/lcc/.


    < Archives associated with comp.compilers contain a great deal of
    < information about available compilers, interpreters, grammars,
    < etc. (for many languages). The comp.compilers archives
    < (including an FAQ list), maintained by the moderator, John R.
    < Levine, are at iecc.com . A list of available compilers and
    < related resources, maintained by Mark Hopkins, Steven Robenalt,
    < and David Muir Sharnoff, is at ftp.idiom.com in pub/compilers-
    < list/. (See also the comp.compilers directory in the
    < news.answers archives at rtfm.mit.edu and ftp.uu.net; see
    < question 20.40.)
    ---
    > Archives associated with the comp.compilers newsgroup contain a
    > great deal of information about available compilers,
    > interpreters, grammars, etc. (for many languages). The
    > comp.compilers archives at http://compilers.iecc.com/ include an
    > FAQ list and a catalog of free compilers.


    ==========

    [Q18.7 Where can I get an ANSI-compatible lint?]

    < A: Products called PC-Lint and FlexeLint (in "shrouded source
    < form," for compilation on 'most any system) are available from
    <
    < Gimpel Software
    < 3207 Hogarth Lane
    < Collegeville, PA 19426 USA
    < (+1) 610 584 4261
    <
    ---
    > A: Products called PC-Lint and FlexeLint are available from Gimpel
    > Software at http://www.gimpel.com/.


    Another ANSI-compatible lint (which can also perform higher-
    < level formal verification) is LCLint, available via anonymous
    < ftp from larch.lcs.mit.edu in pub/Larch/lclint/.
    ---
    > level formal verification) is Splint (formerly lclint) at
    > http://lclint.cs.virginia.edu/.


    ==========

    [Q18.8 Don't ANSI function prototypes render lint obsolete?]

    < A: No.
    ---
    > A: Not really.


    ==========

    [Q18.9 Are there any C tutorials or other resources on the net?]

    < Tom Torfs has a nice tutorial at
    < http://members.xoom.com/tomtorfs/cintro.html .
    ---
    > Tom Torfs has a nice tutorial at http://cprog.tomsweb.net .


    "Notes for C programmers," by Christopher Sawtell, are
    < available from svr-ftp.eng.cam.ac.uk in misc/sawtell_C.shar and
    < garbo.uwasa.fi in /pc/c-lang/c-lesson.zip .
    ---
    > available by ftp from svr-ftp.eng.cam.ac.uk in
    > misc/sawtell_C.shar and garbo.uwasa.fi in pc/c-lang/c-
    > lesson.zip, or on the web at
    > http://www.fi.uib.no/Fysisk/Teori/KURS/OTHER/newzealand.html .


    The Coronado Enterprises C tutorials are available on Simtel
    < mirrors in pub/msdos/c or on the web at http://www.swcp.com/~dodrill .
    ---
    > mirrors in pub/msdos/c or on the web at
    > http://www.coronadoenterprises.com/tutorials/c/index.html .


    < Rick Rowe has a tutorial which is available from ftp.netcom.com
    < as pub/rowe/tutorde.zip or ftp.wustl.edu as
    < pub/MSDOS_UPLOADS/programming/c_language/ctutorde.zip .

    < There is evidently a web-based course at
    < http://www.strath.ac.uk/CC/Courses/CCourse/CCourse.html .
    ---
    > There is a web-based course by Steve Holmes at
    > http://www.strath.ac.uk/IT/Docs/Ccourse/ .


    ==========

    [Q18.10 What's a good book for learning C?]

    Several sets of annotations and errata are available on the net, see
    e.g. http://www.csd.uwo.ca/~jamie/.Refs/.Footnotes/C-annotes.html ,
    http://www.eskimo.com/~scs/cclass/cclass.html , and
    < http://www.lysator.liu.se/c/c-errata.html#main .
    ---
    > http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html .


    < Mitch Wright maintains an annotated bibliography of C and Unix
    < books; it is available for anonymous ftp from ftp.rahul.net in
    < directory pub/mitch/YABL/.

    < Scott McMahon has a nice set of reviews at
    < http://www.skwc.com/essent/cyberreviews.html .

    The Association of C and C++ Users (ACCU) maintains a
    < comprehensive set of bibliographic reviews of C/C++ titles, at
    < http://bach.cis.temple.edu/accu/bookcase or
    < http://www.accu.org/accu .
    <
    ---
    > comprehensive set of bibliographic reviews of C/C++ titles at
    > http://www.accu.org/bookreviews/public/.


    < This FAQ list's editor has a large collection of assorted
    < old recommendations which various people have posted; it
    < is available upon request.

    ==========

    [Q18.13 Where can I find the sources of the standard C libraries?]

    < A: One source (though not public domain) is _The Standard C
    < Library_, by P.J. Plauger (see the Bibliography).
    < Implementations of all or part of the C library have been
    < written and are readily available as part of the NetBSD and GNU
    < (also Linux) projects.
    ---
    > A: The GNU project has a complete implementation at
    > http://www.gnu.org/software/libc/. Another source (though not
    > public domain) is _The Standard C Library_, by P.J. Plauger (see
    > the Bibliography).


    ==========

    [Q18.15 Where can I get a BNF or YACC grammar for C?]

    A: The definitive grammar is of course the one in the ANSI
    < standard; see question 11.2. Another grammar (along with
    < one for C++) by Jim Roskind is in pub/c++grammar1.1.tar.Z
    < at ics.uci.edu (or perhaps ftp.ics.uci.edu, or perhaps
    < OLD/pub/c++grammar1.1.tar.Z), or at ftp.eskimo.com in
    < u/s/scs/roskind_grammar.Z .
    ---
    > standard; see question 11.2. Another grammar by Jim Roskind
    > is available at ftp.eskimo.com in u/s/scs/roskind_grammar.Z .


    < A fleshed-out, working instance of the ANSI grammar
    ---
    > A fleshed-out, working instance of the ANSI C90 grammar
    > (due to Jeff Lee) is on ftp.uu.net (see question 18.16) in
    > usenet/net.sources/ansi.c.grammar.Z (including a companion
    > lexer).


    ==========

    [Q18.15d I need code for performing multiple precision arithmetic.]

    A: Some popular packages are the "quad" functions within the BSD
    Unix libc sources (ftp.uu.net, /systems/unix/bsd-sources/.../
    < /src/lib/libc/quad/*), the GNU MP library, the MIRACL package
    < (see http://indigo.ie/~mscott/ ), and the old Unix libmp.a.
    ---
    > src/lib/libc/quad/*), the GNU MP library "libmp", the MIRACL
    > package (see http://indigo.ie/~mscott/ ), the "calc" program by
    > David Bell and Landon Curt Noll, and the old Unix libmp.a.


    ==========

    [Q19.1 How can I read a single character from the keyboard...]

    < Note that the answers are often not unique even across different
    < variants of a system; bear in mind when answering system-
    ---
    > Note that the answers may differ even across variants of
    > otherwise similar systems (e.g. across different variants of
    > Unix); bear in mind when answering system-specific questions

    that the answer that applies to your system may not apply to
    everyone else's.

    ==========

    [Q19.3 How can I display a percentage-done indication...]

    current line. The character '\b' is a backspace, and will
    < usually move the cursor one position to the left.
    ---
    > usually move the cursor one position to the left. (But remember
    > to call fflush(), too.)


    ==========

    [Q19.8 How can I direct output to the printer?]

    > Under some circumstances, another (and perhaps the only)
    > possibility is to use a window manager's screen-capture
    > function, and print the resulting bitmap.


    ==========

    [Q19.10 How can I do graphics?]

    > A modern, platform-independent graphics library (which also
    > supports 3D graphics and animation) is OpenGL. Other graphics
    > standards which may be of interest are GKS and PHIGS.


    ==========

    [Q19.12 How can I find out the size of a file, prior to reading it in?]

    You can fseek() to the end and then use
    ftell(), or maybe try fstat(), but these tend to have the same
    sorts of problems: fstat() is not portable, and generally tells
    you the same thing stat() tells you; ftell() is not guaranteed
    < to return a byte count except for binary files. Some systems
    ---
    > to return a byte count except for binary files (but, strictly
    > speaking, binary files don't necessarily support fseek to
    > SEEK_END at all). Some systems provide functions called

    filesize() or filelength(), but these are obviously not
    portable, either.

    ==========

    [Q19.20 How can I read a directory in a C program?]

    (MS-DOS also has FINDFIRST and FINDNEXT routines which
    < do essentially the same thing.)
    ---
    > do essentially the same thing, and MS Windows has FindFirstFile
    > and FindNextFile.)


    ==========

    [Q19.23 How can I allocate arrays or structures bigger than 64K?]

    to allocate huge amounts of it contiguously. (The C Standard
    does not guarantee that single objects can be 32K or larger,
    < or 64K for C9X.) Often it's a good idea to use data
    ---
    > or 64K for C99.) Often it's a good idea to use data


    ==========

    [Q19.25 How can I access memory (a memory-mapped device...]

    < Then, *magicloc refers to the location you want.
    ---
    > Then, *magicloc refers to the location you want. If the
    > location is a memory-mapped I/O register, you will probably also
    > want to use the volatile qualifier.


    ==========

    [Q19.27 How can I invoke another program...]

    > Depending on your operating system, you may also be able to use
    > system calls such as exec or spawn (or execl, execv, spawnl,
    > spawnv, etc.).


    ==========

    [Q19.37 How can I implement a delay... with sub-second resolution?]

    < A: Unfortunately, there is no portable way. V7 Unix, and derived
    < systems, provided a fairly useful ftime() function with
    < resolution up to a millisecond, but it has disappeared from
    < System V and POSIX. Other routines you might look for on your
    ---
    > A: Unfortunately, there is no portable way. Routines you might
    > look for on your system include clock(), delay(), ftime(),
    > gettimeofday(), msleep(), nap(), napms(), nanosleep(),
    > setitimer(), sleep(), Sleep(), times(), and usleep().


    ==========

    [Q19.40 How do I... Use sockets? Do networking?]

    and W. R. Stevens's _UNIX Network Programming_. There is also
    plenty of information out on the net itself, including the
    < "Unix Socket FAQ" at http://kipper.york.ac.uk/~vic/sock-faq/
    ---
    > "Unix Socket FAQ" at http://www.developerweb.net/sock-faq/


    > and "Beej's Guide to Network Programming" at
    > http://www.ecst.csuchico.edu/~beej/guide/net/.


    > (One tip: depending on your OS, you may need to explicitly
    > request the -lsocket and -lnsl libraries; see question 13.25.)


    ==========

    [Q20.14 Are pointers really faster than arrays?]

    < It is "usually" faster to march through large arrays with
    ---
    > For conventional machines, it is usually faster to march through
    > large arrays with pointers rather than array subscripts, but for
    > some processors the reverse is true.


    ==========

    [Q20.20 Why don't C comments nest? ...]

    < Note also that // comments, as in C++, are not yet legal in C,
    < so it's not a good idea to use them in C programs (even if your
    < compiler supports them as an extension).
    ---
    > Note also that // comments have only become legal in C as of
    > C99.


    ==========

    < 20.20b: Is C a great language, or what? Where else could you write
    ---
    > 20.21b: Is C a great language, or what? Where else could you write

    something like a+++++b ?

    ==========

    [Q20.27 ... Can I use a C++ compiler to compile C code?]

    < compilation modes. See also questions 8.9 and 20.20.
    ---
    > compilation modes. (But it's usually a bad idea to compile
    > straight C code as if it were C++; the languages are different
    > enough that you'll generally get poor results.) See also
    > questions 8.9 and 20.20.


    ==========

    < 20.32: Will 2000 be a leap year? Is (year % 4 == 0) an accurate test
    < for leap years?
    ---
    > 20.32: Is (year % 4 == 0) an accurate test for leap years? (Was 2000 a
    > leap year?)


    < A: Yes and no, respectively. The full expression for the present
    < Gregorian calendar is
    ---
    > A: No, it's not accurate (and yes, 2000 was a leap year).
    > The full expression for the present Gregorian calendar is


    ==========

    [Q20.34 ...how do you write a program which produces its own source code...?]

    < (This program, like many of the genre, neglects to #include
    < <stdio.h>, and assumes that the double-quote character " has the
    ---
    > (This program has a few deficiencies, among other things
    > neglecting to #include <stdio.h>, and assuming that the double-

    quote character " has the value 34, as it does in ASCII.)

    > Here is an improved version, posted by James Hu:
    >
    > #define q(k)main(){return!puts(#k"\nq("#k")");}
    > q(#define q(k)main(){return!puts(#k"\nq("#k")");})


    ==========

    [Q20.35 What is "Duff's Device"?]

    < A: It's a devastatingly deviously unrolled byte-copying loop,
    < devised by Tom Duff while he was at Lucasfilm. In its "classic"
    < form, it looks like:
    ---
    > A: It's a devastatingly devious way of unrolling a loop, devised by
    > Tom Duff while he was at Lucasfilm. In its "classic" form, it
    > was used to copy bytes, and looked like this:


    ==========

    [Q20.38 Where does the name "C" come from, anyway?]

    A: C was derived from Ken Thompson's experimental language B, which
    was inspired by Martin Richards's BCPL (Basic Combined
    Programming Language), which was a simplification of CPL
    < (Cambridge Programming Language).
    ---
    > (Combined Programming Language, or perhaps Cambridge Programming
    > Language).


    ==========

    [Q20.40 Where can I get extra copies of this list?]

    < What about back issues?

    < This list is an evolving document containing questions which
    < have been Frequent since before the Great Renaming; it is not
    < just a collection of this month's interesting questions. Older
    < copies are obsolete and don't contain much, except the
    < occasional typo, that the current list doesn't.

    ==========

    [Bibliography]

    Samuel P. Harbison and Guy L. Steele, Jr., _C: A Reference Manual_,
    < Fourth Edition, Prentice-Hall, 1995, ISBN 0-13-326224-3. [H&S]
    ---
    > Fourth Edition, Prentice-Hall, 1995, ISBN 0-13-326224-3. [There is
    > also a fifth edition: 2002, ISBN 0-13-089592-X.] [H&S]


    Donald E. Knuth, _The Art of Computer Programming_. Volume 1:
    < _Fundamental Algorithms_, Second Edition, Addison-Wesley, 1973, ISBN
    < 0-201-03809-9. Volume 2: _Seminumerical Algorithms_, Second Edition,
    < Addison-Wesley, 1981, ISBN 0-201-03822-6. Volume 3: _Sorting and
    < Searching_, Addison-Wesley, 1973, ISBN 0-201-03803-X. (New editions
    < are coming out!) [Knuth]
    ---
    > _Fundamental Algorithms_, Third Edition, Addison-Wesley, 1997, ISBN
    > 0-201-89683-4. Volume 2: _Seminumerical Algorithms_, Third Edition,
    > 1997, ISBN 0-201-89684-2. Volume 3: _Sorting and Searching_, Second
    > Edition, 1998, ISBN 0-201-89685-0. [Knuth]


    Robert Sedgewick, _Algorithms in C_, Addison-Wesley, 1990,
    < ISBN 0-201-51425-7. (A new edition is being prepared;
    < the first half is ISBN 0-201-31452-5.)
    ---
    > ISBN 0-201-51425-7. (A new edition is being prepared; the first two
    > volumes are ISBN 0-201-31452-5 and 0-201-31663-3.)


    > Peter van der Linden, _Expert C Programming: Deep C Secrets_, Prentice
    > Hall, 1994, ISBN 0-13-177429-8.


    ==========

    [Acknowledgements]

    > Thanks to Jamshid Afshar, Lauri Alanko, Michael B. Allen, David
    > Anderson, Jens Andreasen, Tanner Andrews, Sudheer Apte, Joseph
    > Arceneaux, Randall Atkinson, Kaleb Axon, Daniel Barker, Rick Beem, Peter
    > Bennett, Mathias Bergqvist, Wayne Berke, Dan Bernstein, Tanmoy
    > Bhattacharya, John Bickers, Kevin Black, Gary Blaine, Yuan Bo, Mark J.
    > Bobak, Anthony Borla, Dave Boutcher, Alan Bowler, ,

    Michael Bresnahan, Walter Briscoe, Vincent Broman, Robert T. Brown, Stan
    Brown, John R. Buchan, Joe Buehler, Kimberley Burchett, Gordon Burditt,
    > Scott Burkett, Eberhard Burr, Burkhard Burow, Conor P. Cahill, D'Arcy

    J.M. Cain, Christopher Calabrese, Ian Cargill, Vinit Carpenter, Paul
    Carter, Mike Chambers, Billy Chambless, C. Ron Charlton, Franklin Chen,
    Jonathan Chen, Raymond Chen, Richard Cheung, Avinash Chopde, Steve
    Clamage, Ken Corbin, Dann Corbit, Ian Cottam, Russ Cox, Jonathan
    > Coxhead, Lee Crawford, Nick Cropper, Steve Dahmer, Jim Dalsimer, Andrew
    > Daviel, James Davies, John E. Davis, Ken Delong, Norm Diamond, Jamie
    > Dickson, Bob Dinse, dlynes@plenary-software, Colin Dooley, Jeff Dunlop,
    > Ray Dunn, Stephen M. Dunn, Andrew Dunstan, Michael J. Eager, Scott

    Ehrlich, Arno Eigenwillig, Yoav Eilat, Dave Eisen, Joe English, Bjorn
    > Engsig, David Evans, Andreas Fassl, Clive D.W. Feather, Dominic Feeley,
    > Simao Ferraz, Pete Filandr, Bill Finke Jr., Chris Flatters, Rod Flores,

    Alexander Forst, Steve Fosdick, Jeff Francis, Ken Fuchs, Tom Gambill,
    > Dave Gillespie, Samuel Goldstein, Willis Gooch, Tim Goodwin, Alasdair
    > Grant, W. Wesley Groleau, Ron Guilmette, Craig Gullixson, Doug Gwyn,
    > Michael Hafner, Zhonglin Han, Darrel Hankerson, Tony Hansen, Douglas

    Wilhelm Harder, Elliotte Rusty Harold, Joe Harrington, Guy Harris, John
    > Hascall, Adrian Havill, Richard Heathfield, Des Herriott, Ger Hobbelt,
    > Sam Hobbs, Joel Ray Holveck, Jos Horsmeier, Syed Zaeem Hosain, Blair
    > Houghton, Phil Howard, Peter Hryczanek, James C. Hu, Chin Huang, Jason
    > Hughes, David Hurt, Einar Indridason, Vladimir Ivanovic, Jon Jagger,
    > Ke Jin, Kirk Johnson, David Jones, Larry Jones, Morris M. Keesan, Arjan
    > Kenter, Bhaktha Keshavachar, James Kew, Bill Kilgore, Darrell Kindred,

    Lawrence Kirby, Kin-ichi Kitano, Peter Klausler, John Kleinjans, Andrew
    > Koenig, Thomas Koenig, Adam Kolawa, Jukka Korpela, Przemyslaw Kowalczyk,
    > Ajoy Krishnan T, Anders Kristensen, Jon Krom, Markus Kuhn, Deepak
    > Kulkarni, Yohan Kun, B. Kurtz, Kaz Kylheku, Oliver Laumann, John Lauro,
    > Felix Lee, Mike Lee, Timothy J. Lee, Tony Lee, Marty Leisner, Eric
    > Lemings, Dave Lewis, Don Libes, Brian Liedtke, Philip Lijnzaad, James
    > D. Lin, Keith Lindsay, Yen-Wei Liu, Paul Long, Patrick J. LoPresti,
    > Christopher Lott, Tim Love, Paul Lutus, Mike McCarty, Tim McDaniel,
    > Michael MacFaden, Allen Mcintosh, J. Scott McKellar, Kevin McMahon,

    Stuart MacMartin, John R. MacMillan, Robert S. Maier, Andrew Main,
    Bob Makowski, Evan Manning, Barry Margolin, George Marsaglia, George
    Matas, Brad Mears, Wayne Mery, De Mickey, Rich Miller, Roger Miller,
    Bill Mitchell, Mark Moraes, Darren Morby, Bernhard Muenzer, David Murphy,
    Walter Murray, Ralf Muschall, Ken Nakata, Todd Nathan, Taed Nelson,
    > Pedro Zorzenon Neto, Daniel Nielsen, Landon Curt Noll, Tim Norman, Paul

    Nulsen, David O'Brien, Richard A. O'Keefe, Adam Kolawa, Keith Edward
    > O'hara, James Ojaste, Max Okumoto, Hans Olsson, Thomas Otahal, Lloyd
    > Parkes, Bob Peck, Harry Pehkonen, Andrew Phillips, Christopher Phillips,

    Francois Pinard, Nick Pitfield, Wayne Pollock, , Dan Pop,
    > Don Porges, Claudio Potenza, Lutz Prechelt, Lynn Pye, Ed Price, Kevin
    > D. Quitt, Pat Rankin, Arjun Ray, Eric S. Raymond, Christoph Regli,
    > Peter W. Richards, James Robinson, Greg Roelofs, Eric Roode, Manfred
    > Rosenboom, J.M. Rosenstock, Rick Rowe, Michael Rubenstein, Erkki
    > Ruohtula, John C. Rush, John Rushford, Kadda Sahnine, Tomohiko Sakamoto,

    Matthew Saltzman, Rich Salz, Chip Salzenberg, Matthew Sams, Paul Sand,
    DaviD W. Sanderson, Frank Sandy, Christopher Sawtell, Jonas Schlein,
    Paul Schlyter, Doug Schmidt, Rene Schmit, Russell Schulz, Dean Schulze,
    > Jens Schweikhardt, Chris Sears, Peter Seebach, Gisbert W. Selke,
    > Patricia Shanahan, Girija Shanker, Clinton Sheppard, Aaron Sherman,
    > Raymond Shwake, Nathan Sidwell, Thomas Siegel, Peter da Silva, Andrew
    > Simmons, Joshua Simons, Ross Smith, Thad Smith, Henri Socha, Leslie
    > J. Somos, Eric Sosman, Henry Spencer, David Spuler, Frederic Stark,

    James Stern, Zalman Stern, Michael Sternberg, Geoff Stevens, Alan
    > Stokes, Bob Stout, Dan Stubbs, Tristan Styles, Richard Sullivan, Steve
    > Sullivan, Melanie Summit, Erik Talvola, Christopher Taylor, Dave Taylor,
    > Clarke Thatcher, Wayne Throop, Chris Torek, Steve Traugott, Brian Trial,

    Nikos Triantafillis, Ilya Tsindlekht, Andrew Tucker, Goran Uddeborg,
    > Rodrigo Vanegas, Jim Van Zandt, Momchil Velikov, Wietse Venema, Tom

    Verhoeff, Ed Vielmetti, Larry Virden, Chris Volpe, Mark Warren, Alan
    Watson, Kurt Watzka, Larry Weiss, Martin Weitzel, Howard West, Tom
    > White, Freek Wiedijk, Stephan Wilms, Tim Wilson, Dik T. Winter, Lars
    > Wirzenius, Dave Wolverton, Mitch Wright, Conway Yee, James Youngman,

    Ozan S. Yigit, and Zhuo Zang, who have contributed, directly or
    indirectly, to this article.

    ====================


    Next, here are all sorts of minor wording changes and cosmetic
    differences:

    ==========
    < [Last modified February 7, 1999 by scs.]
    ---
    > [Last modified July 3, 2004 by scs.]

    ==========
    Certain topics come up again and again on this newsgroup. They are good
    questions, and the answers may not be immediately obvious, but each time
    they recur, much net bandwidth and reader time is wasted on repetitive
    < responses, and on tedious corrections to the incorrect answers which are
    < inevitably posted.
    ---
    > responses, and on tedious corrections to any incorrect answers which may
    > unfortunately be posted.

    ==========
    If you have a question about C which is not answered in this article,
    < first try to answer it by checking a few of the referenced books, or by
    < asking knowledgeable colleagues, before posing your question to the net
    ---
    > books, or one of the expanded versions mentioned below, before posing

    your question to the net at large.
    ==========
    (However, this is a large and heavy document, so don't
    < assume that everyone on the newsgroup has managed to read all of it in
    ---
    > assume that everyone on the net has managed to read all of it in detail,

    and please don't roll it up and thwack people over the head with it just
    because they missed their answer in it.)
    ==========
    < be able to obtain the most up-to-date copy on the web at
    ---
    > be able to obtain the most up-to-date copy at

    http://www.eskimo.com/~scs/C-faq/top.html or http://www.faqs.org/faqs/ ,
    ==========
    < or from one of the ftp sites mentioned in question 20.40.
    ---
    > or via ftp from ftp://rtfm.mit.edu/. (See also question 20.40.)

    ==========
    Since this list is modified from time to time, its question numbers
    may not match those in older or newer copies which are in circulation;
    < be careful when referring to FAQ list entries by number alone.
    ---
    > so be careful when referring to FAQ list entries by number alone.

    ==========
    < Other versions of this document are also available. Posted along
    ---
    > Several other versions of this document are available. Posted along

    with it are an abridged version and (when there are changes) a list of
    ==========
    < is available on the web at the aforementioned URL. Finally, for those
    < who might prefer a bound, hardcopy version (and even longer answers to
    < even more questions!), a book-length version has been published by
    < Addison-Wesley (ISBN 0-201-84519-9).
    ---
    > is available on the web at the aforementioned URL. For those who might
    > prefer a bound, hardcopy version, a book-length version has been
    > published by Addison-Wesley (ISBN 0-201-84519-9). The hypertext and
    > book versions include additional questions and more detailed answers, so
    > you might want to check one of them if you still have questions after
    > reading this posted list.

    ==========
    < This article is always being improved. Your input is welcomed. Send
    ---
    > This article can always be improved. Your input is welcome. Send

    your comments to .
    ==========
    < 1.1: How do you decide which integer type to use?
    ---
    > 1.1: How should I decide which integer type to use?

    ==========
    < float and double. None of the above rules apply if the address
    < of a variable is taken and must have a particular type.
    ---
    > float and double. None of the above rules apply if pointers to
    > the variable must have a particular type.

    ==========
    < 1.4: What should the 64-bit type on a machine that can support it?
    ---
    > 1.4: What should the 64-bit type be on a machine that can support it?

    ==========
    The .c file containing the definition should also #include the
    < same header file, so that the compiler can check that the definition
    ---
    > same header file, so the compiler can check that the definition

    matches the declarations.
    ==========
    clear. The problem with the NODEPTR example is that the typedef
    < has not been defined at the point where the "next" field is
    ---
    > has not yet been defined at the point where the "next" field is

    declared.
    ==========
    < 1.21: How do I declare an array of N pointers to functions returning
    < pointers to functions returning pointers to characters?
    ---
    > 1.21: How do I construct and understand declarations of complicated
    > types such as "array of N pointers to functions returning
    > pointers to functions returning pointers to char"?

    ==========
    < A: The first part of this question can be answered in at least
    < three ways:
    ---
    > A: There are at least three ways of answering this question:

    ==========
    cdecl can also explain complicated declarations, help with
    < casts, and indicate which set of parentheses the arguments
    ---
    > casts, and indicate which set of parentheses the parameters

    go in
    ==========
    < Any good book on C should explain how to read these complicated C
    ---
    > A good book on C should explain how to read these complicated

    declarations "inside out" to understand them ("declaration
    mimics use").
    ==========
    1.30: What am I allowed to assume about the initial values
    < of variables which are not explicitly initialized?
    ---
    > of variables and arrays which are not explicitly initialized?

    ==========
    A: Uninitialized variables with "static" duration (that is, those
    declared outside of functions, and those declared with the
    < storage class static), are guaranteed to start out as zero,
    ---
    > storage class static), are guaranteed to start out as zero, just

    as if the programmer had typed "= 0".
    ==========
    A: Is the declaration of a static or non-local variable? Function
    < calls are allowed only in initializers for automatic variables
    ---
    > calls are allowed in initializers only for automatic variables

    ==========
    A: A string literal can be used in two slightly different ways. As
    < an array initializer (as in the declaration of char a[]), it
    ---
    > an array initializer (as in the declaration of char a[] in the
    > question), it specifies the initial values of the characters in

    that array.
    ==========
    Anywhere else, it turns into an unnamed, static array of
    characters, which may be stored in read-only memory,
    < which is why you can't safely modify it.
    ---
    > and which therefore cannot necessarily be modified.

    ==========
    (For compiling old code, some compilers have a switch
    < controlling whether strings are writable or not.)
    ---
    > controlling whether string literals are writable or not.)

    ==========
    < When the name of a function appears in an expression like this,
    ---
    > When the name of a function appears in an expression,

    it "decays" into a pointer (that is, it has its address
    implicitly taken), much as an array name does.
    ==========
    < 2.4: What's the best way of implementing opaque (abstract) data types
    < in C?
    ---
    > 2.4: How can I implement opaque (abstract) data types in C?

    ==========
    < A: No. There is no single, good way for a compiler to implement
    < implicit structure comparison (i.e. to support the == operator
    ---
    > A: No. There is not a good way for a compiler to implement
    > structure comparison (i.e. to support the == operator

    for structures) which is consistent with C's low-level flavor.
    ==========
    A simple byte-by-byte comparison could founder on random bits
    < present in unused "holes" in the structure (such padding is used
    < to keep the alignment of later fields correct; see question 2.12).
    ---
    > present in unused "holes" in the structure (see question 2.12).

    ==========
    < Note also that if the structure contains any pointers, only
    ---
    > Also, if the structure contains any pointers, only

    the pointer values will be written, and they are most unlikely
    to be valid when read back in.
    ==========
    Finally, note that for widespread portability you must use the
    < "b" flag when fopening the files; see question 12.38.
    ---
    > "b" flag when opening the files; see question 12.38.

    ==========
    < A: Structures may have this padding (as well as internal padding),
    < if necessary, to ensure that alignment properties will be
    < preserved when an array of contiguous structures is allocated.
    < Even when the structure is not part of an array, the end padding
    ---
    > A: Padding at the end of a structure may be necessary to preserve
    > alignment when an array of contiguous structures is allocated.
    > Even when the structure is not part of an array, the padding

    remains, so that sizeof can always return a consistent size.
    ==========
    < A: At the present time, there is little difference. The C Standard
    ---
    > A: There is little difference. The C Standard

    says that enumerations may be freely intermixed with other
    integral types, without errors.
    ==========
    that they obey block scope. (A compiler may also generate
    < nonfatal warnings when enumerations and integers are
    < indiscriminately mixed, since doing so can still be considered
    < bad style even though it is not strictly illegal.)
    ---
    > nonfatal warnings when enumerations are indiscriminately mixed,
    > since doing so can still be considered bad style.)

    ==========
    (Loosely speaking, by "multiple, ambiguous side effects" we mean
    < any combination of ++, --, =, +=, -=, etc. in a single expression
    ---
    > any combination of increment, decrement, and assignment operators

    in a single expression which causes the same object either to be
    modified twice or modified and then inspected.
    ==========
    < Note that (long int)(a * b) would *not* have the desired effect.
    ---
    > Notice that (long int)(a * b) would *not* have the desired
    > effect.

    ==========
    < or a delibrate but nonstandard extension if a particular
    ---
    > or a deliberate but nonstandard extension if a particular

    ==========
    < Whenever possible, you should choose appropriate pointer types
    < in the first place, instead of trying to treat one type
    ---
    > When possible, however, you should choose appropriate pointer
    > types in the first place, rather than trying to treat one type

    as another.
    ==========
    < void * acts as a generic pointer only because conversions are
    ---
    > void * acts as a generic pointer only because conversions (if
    > necessary) are applied automatically when other pointer types

    are assigned to and from void *'s;
    ==========
    < 4.12: I've seen different methods used for calling functions via
    ---
    > 4.12: I've seen different syntax used for calling functions via

    pointers. What's the story?
    ==========
    pointers, and that "real" function names always decay implicitly
    into pointers (in expressions, as they do in initializations;
    < see question 1.34). This reasoning (which is in fact used in
    < the ANSI standard) means that
    ---
    > see question 1.34). This reasoning means that

    ==========
    function pointer followed by an argument list except call the
    < function pointed to.) An explicit * is still allowed.
    ---
    > function pointed to.)

    ==========
    > The ANSI C Standard essentially adopts the latter
    > interpretation, meaning that the explicit * is not required,
    > though it is still allowed.

    ==========
    < 5.4: What is NULL and how is it #defined?
    ---
    > 5.4: What is NULL and how is it defined?

    ==========
    < preprocessor macro NULL is #defined (by <stdio.h> and several
    < other headers) with the value 0, possibly cast to (void *)
    ---
    > preprocessor macro NULL is defined (by <stdio.h> and several
    > other headers) as a null pointer constant, typically 0 or
    > ((void *)0)

    ==========
    < NULL should *only* be used for pointers; see question 5.9.
    ---
    > NULL should be used *only* as a pointer constant; see question 5.9.

    ==========
    < A: Not in general. The complication is that there are machines
    ---
    > A: Not in the most general case. The complication is that there

    are machines which use different internal representations for
    pointers to different types of data.
    ==========
    < pointer arguments of other types would still be problematical,
    ---
    > pointer arguments of other types could still (in the absence
    > of prototypes) be problematical,

    ==========
    This article uses the phrase "null pointer" (in lower case) for
    < sense 1, the character "0" or the phrase "null pointer constant"
    ---
    > sense 1, the token "0" or the phrase "null pointer constant"

    for sense 3, and the capitalized word "NULL" for sense 4.
    ==========
    < A: C programmers traditionally like to know more than they might
    < need to about the underlying machine implementation.
    ---
    > A: C programmers traditionally like to know a lot (perhaps more
    > than they need to) about the underlying machine implementation.

    ==========
    integer zero instead of an error message, and if that uncast 0
    < was supposed to be a null pointer constant, the code may not
    < work.
    ---
    > was supposed to be a null pointer constant, the resulting
    > program may not work.

    ==========
    Some 64-bit Cray machines represent int * in the lower 48 bits
    < of a word; char * additionally uses the upper 16 bits to
    ---
    > of a word; char * additionally uses some of the upper 16 bits to

    indicate a byte address within a word.
    ==========
    A: This message, which typically occurs with MS-DOS compilers, means
    < that you've written, via a null (perhaps because uninitialized)
    < pointer, to an invalid location (probably offset 0 in the
    < default data segment).
    ---
    > means that you've written, via a null pointer, to an invalid
    > location -- probably offset 0 in the default data segment.

    ==========
    < A: In one source file you defind an array of characters and in the
    ---
    > A: In one source file you defined an array of characters and in the

    ==========
    < It is important to realize that a reference like x[3] generates
    ---
    > It is useful to realize that a reference like x[3] generates

    different code depending on whether x is an array or a pointer.
    ==========
    < If you can't use C9X or gcc, you'll have to use malloc(), and
    ---
    > If you can't use C99 or gcc, you'll have to use malloc(), and

    remember to call free() before the function returns.
    ==========
    < Finally, in C9X you can use a variable-length array.
    ---
    > Finally, in C99 you can use a variable-length array.

    ==========
    A: The rule (see question 6.3) by which arrays decay into pointers
    < is not applied recursively.
    ---
    > is *not* applied recursively.

    ==========
    not provide an automatically-managed string type. C compilers
    < only allocate memory for objects explicitly mentioned in the
    ---
    > allocate memory only for objects explicitly mentioned in the

    source code (in the case of strings, this includes character
    ==========
    < A: You got lucky, I guess. The memory pointed to by the
    < unitialized pointer p happened to be writable by you,
    ---
    > A: You got lucky, I guess. The memory randomly pointed to by
    > the uninitialized pointer p happened to be writable by you,

    ==========
    A pointer value which has been freed is, strictly speaking,
    < invalid, and *any* use of it, even if is not dereferenced,
    ---
    > invalid, and *any* use of it, even if it is not dereferenced,

    can theoretically lead to trouble,
    ==========
    A: In C, characters are represented by small integers corresponding
    < to their values (in the machine's character set), so you
    ---
    > to their values in the machine's character set. Therefore, you

    don't need a conversion function: if you have the character, you
    have its value.
    ==========
    < DEBUG("i = %d" _ i)
    ---
    > DEBUG("i = %d" _ i);

    ==========
    controversial trigraph sequences). The ANSI C standard also
    < formalizes the C run-time library support routines.
    ---
    > formalized the C run-time library support routines.

    ==========
    < The text of the Rationale (not the full Standard) can be
    < obtained by anonymous ftp from ftp.uu.net (see question 18.16)
    < in directory doc/standards/ansi/X3.159-1989, and is also
    < available on the web at http://www.lysator.liu.se/c/rat/title.html .
    < The Rationale has also been printed by Silicon Press,
    < ISBN 0-929306-07-4.
    ---
    > The text of the original ANSI Rationale can be obtained by
    > anonymous ftp from ftp.uu.net (see question 18.16) in directory
    > doc/standards/ansi/X3.159-1989, and is also available on the web
    > at http://www.lysator.liu.se/c/rat/title.html . That Rationale
    > has also been printed by Silicon Press, ISBN 0-929306-07-4.

    ==========
    < Public review drafts of C9X are available from ISO/IEC
    ---
    > Public review drafts of C9X were available from ISO/IEC

    ==========
    11.5: Why does the declaration
    extern int f(struct x *p);
    < give me an obscure warning message about "struct x introduced in
    < prototype scope"?
    ---
    > give me an obscure warning message about "struct x declared
    > inside parameter list"?

    ==========
    A: "const char *p" (which can also be written "char const *p")
    declares a pointer to a constant character (you can't change
    < the character); "char * const p" declares a constant pointer
    ---
    > any pointed-to characters); "char * const p" declares a constant

    pointer to a (variable) character (i.e. you can't change the
    pointer).
    ==========
    < A: The problem is older linkers which are under the control of
    ---
    > A: The problem is linkers which are under control of

    neither the ANSI/ISO Standard nor the C compiler developers
    on the systems which have them.
    ==========
    If you're interested in writing portable code, you can ignore
    < the distinctions, as you'll want to avoid code that depends
    ---
    > the distinctions, as you'll usually want to avoid code that

    depends on any of the three behaviors.
    ==========
    A: The functions in <locale.h> begin to provide some support for
    < these operations, but there is no standard routine for doing
    ---
    > these operations, but there is no standard function for doing

    either task.
    ==========
    < If you're worried about using floating point, you could use
    ---
    > If you'd rather not use floating point, another method is

    rand() / (RAND_MAX / N + 1)
    ==========
    < A: In general, a header file contains only declarations.
    ---
    > A: In general, a header file contains only external declarations.

    ==========
    how carefully your compiler's binary/decimal conversion routines
    (such as those used by printf) have been written, you may see
    < discrepancies when numbers (especially low-precision floats) not
    < exactly representable in base 2 are assigned or read in and then
    ---
    > discrepancies when numbers not exactly representable in base 2

    are assigned or read in and then printed (i.e. converted from
    base 10 to base 2 and back again).
    ==========
    < Another possibility is to to format the value in question using
    ---
    > Another possibility is to format the value in question using

    sprintf(): on many systems it generates strings like "NaN"
    ==========
    < A: Some compilers for small machines, including Borland's
    ---
    > A: Some compilers for small machines, including Turbo C

    Ritchie's original PDP-11 compiler), leave out certain floating
    ==========
    < char *vstrcat(char *first, ...)
    ---
    > char *vstrcat(const char *first, ...)

    ==========
    < void error(char *fmt, ...)
    ---
    > void error(const char *fmt, ...)

    ==========
    < examples in questions 5.2 and 15.4). Finally, if their types
    ---
    > examples in questions 5.2 and 15.4). Finally, if the types
    > are predictable, you can pass an explicit count of the number of

    ==========
    < local arrays. Many systems have fixed-size stacks, and
    ---
    > local arrays. Many systems have fixed-size stacks, and even

    those which perform dynamic stack allocation automatically
    (e.g. Unix) can be confused when the stack tries to grow by a
    huge chunk all at once.
    ==========
    < 16.8: What do "Segmentation violation" and "Bus error" mean?
    ---
    > 16.8: What do "Segmentation violation", "Bus error", and "General
    > protection fault" mean?

    ==========
    < Finally, the author of this FAQ list teaches a C class
    < and has placed its notes on the web; they are at
    ---
    > Finally, the author of this FAQ list once taught a couple of
    > C classes and has placed their notes on the web; they are at

    ==========
    < 18.10: What's a good book for learning C?
    ---
    > 18.10: What's a good book for learning C? What about advanced books
    > and references?

    ==========
    < The GNU libplot package maintains the same spirit and supports
    < many modern plot devices;
    < see http://www.gnu.org/software/plotutils/plotutils.html .
    ---
    > The GNU libplot library, written by Robert Maier, maintains
    > the same spirit and supports many modern plot devices; see
    > http://www.gnu.org/software/plotutils/plotutils.html .

    ==========
    A: If the "size of a file" is the number of characters you'll be
    < able to read from it in C, it is difficult or impossible to
    ---
    > able to read from it in C, it can be difficult or impossible to

    determine this number exactly.
    ==========
    < readdir() only returns file names; if you need more
    ---
    > readdir() returns just the file names; if you need more

    information about the file, try calling stat().
    ==========
    < (Also, remember to call pclose().)
    ---
    > (Also, remember to call pclose() when you're done.)

    ==========
    busy-wait, but this is only an option on a single-user, single-
    < tasking machine as it is terribly antisocial to any other
    ---
    > tasking machine, as it is terribly antisocial to any other

    processes. Under a multitasking operating system, be sure to
    ==========
    It is possible, and desirable, for *most* of a program to be
    ANSI-compatible, deferring the system-dependent functionality to
    < a few routines in a few files which are rewritten for each
    < system ported to.
    ---
    > a few routines in a few files which are either heavily #ifdeffed
    > or rewritten entirely for each system ported to.

    ==========
    or have the function return a structure containing the
    < desired values, or (in a pinch) consider global variables.
    ---
    > desired values, or (in a pinch) you could theoretically use

    global variables.
    ==========
    is not only clearer to the human reader, it is more likely to be
    recognized by the compiler and turned into the most-efficient
    < code (e.g. using a swap instruction, if available).
    ---
    > code (e.g. perhaps even using an EXCH instruction).

    ==========
    < More information may be found in FORT.gz by Glenn Geers, available
    < via anonymous ftp from suphys.physics.su.oz.au in the src
    < directory.
    <
    < cfortran.h, a C header file, simplifies C/FORTRAN interfacing on
    < many popular machines. It is available via anonymous ftp from
    < zebra.desy.de or at http://www-zeus.desy.de/~burow .
    ---
    > For FORTRAN, more information may be found in FORT.gz by Glenn
    > Geers, available via anonymous ftp from suphys.physics.su.oz.au
    > in the src directory. Burkhard Burow's header file cfortran.h
    > simplifies C/FORTRAN interfacing on many popular machines.
    > It is available via anonymous ftp from zebra.desy.de or at
    > http://www-zeus.desy.de/~burow .

    ==========
    This FAQ list's maintainer also has available a list of a few
    < other commercial translation products, and some for more obscure
    < languages.
    ---
    > other translators.

    ==========
    < A: The contest is in a state of flux; see
    ---
    > A: The contest schedule varies over time; see

    ====================


    Finally, here are a few questions which don't really need to be in
    the posted-to-Usenet list every month. (As mentioned, though, they'll
    live on in the web-based version.)

    ==========

    < 1.22: How can I declare a function that can return a pointer to a
    < function of the same type? I'm building a state machine with
    < one function for each state, each of which returns a pointer to
    < the function for the next state. But I can't find a way to
    < declare the functions.
    <
    < A: You can't quite do it directly. Either have the function return
    < a generic function pointer, with some judicious casts to adjust
    < the types as the pointers are passed around; or have it return a
    < structure containing only a pointer to a function returning that
    < structure.

    ==========

    < 2.7: I heard that structures could be assigned to variables and
    < passed to and from functions, but K&R1 says not.
    <
    < A: What K&R1 said (though this was quite some time ago by now) was
    < that the restrictions on structure operations would be lifted
    < in a forthcoming version of the compiler, and in fact structure
    < assignment and passing were fully functional in Ritchie's
    < compiler even as K&R1 was being published. A few ancient C
    < compilers may have lacked these operations, but all modern
    < compilers support them, and they are part of the ANSI C
    < standard, so there should be no reluctance to use them.
    <
    < (Note that when a structure is assigned, passed, or returned,
    < the copying is done monolithically; the data pointed to by any
    < pointer fields is *not* copied.)

    ==========

    < 13.14b: Does C have any Year 2000 problems?
    <
    < A: No, although poorly-written C programs do.
    <
    < The tm_year field of struct tm holds the value of the year minus
    < 1900; this field will therefore contain the value 100 for the
    < year 2000. Code that uses tm_year correctly (by adding or
    < subtracting 1900 when converting to or from human-readable
    < 4-digit year representations) will have no problems at the turn
    < of the millennium. Any code that uses tm_year incorrectly,
    < however, such as by using it directly as a human-readable
    < 2-digit year, or setting it from a 4-digit year with code like
    <
    < tm.tm_year = yyyy % 100; /* WRONG */
    <
    < or printing it as an allegedly human-readable 4-digit year with
    < code like
    <
    < printf("19%d", tm.tm_year); /* WRONG */
    <
    < will have grave y2k problems indeed. See also question 20.32.

    ==========

    < 13.24: I'm trying to port this A: Those functions are variously
    < old program. Why do I obsolete; you should
    < get "undefined external" instead:
    < errors for:
    <
    < index? use strchr.
    < rindex? use strrchr.
    < bcopy? use memmove, after
    < interchanging the first and
    < second arguments (see also
    < question 11.25).
    < bcmp? use memcmp.
    < bzero? use memset, with a second
    < argument of 0.

    ==========

    < 15.7: I have a pre-ANSI compiler, without <stdarg.h>. What can I do?
    <
    < A: There's an older header, <varargs.h>, which offers about the
    < same functionality.

    ==========

    < 18.5: How can I shut off the "warning: possible pointer alignment
    < problem" message which lint gives me for each call to malloc()?
    <
    < A: The problem is that traditional versions of lint do not know,
    < and cannot be told, that malloc() "returns a pointer to space
    < suitably aligned for storage of any type of object." It is
    < possible to provide a pseudoimplementation of malloc(), using a
    < #define inside of #ifdef lint, which effectively shuts this
    < warning off, but a simpleminded definition will also suppress
    < meaningful messages about truly incorrect invocations. It may
    < be easier simply to ignore the message, perhaps in an automated
    < way with grep -v. (But don't get in the habit of ignoring too
    < many lint messages, otherwise one day you'll overlook a
    < significant one.)

    ====================

    Steve Summit
     
    Steve Summit, Jul 4, 2004
    #1
    1. Advertising

  2. Steve Summit

    Steve Summit Guest

    Archive-name: C-faq/diff
    Comp-lang-c-archive-name: C-FAQ-list.diff
    URL: http://www.eskimo.com/~scs/C-faq/top.html

    This is a repost of the many differences between the previous
    version of the comp.lang.c FAQ list (version 3.5, last modified
    February 7, 1999) and the new one, first posted July 3, 2004.

    I have scoured my archives for every unacknowledged suggestion and
    promised improvement, so for once I can say: this update is mostly
    complete. At this point, if you've sent me a suggestion which I
    haven't acknowledged or which isn't reflected here, I guess it
    wouldn't hurt if you sent it again.

    This update has been so long delayed that some of its improvements
    (such as the "new" question 19.17c) are already mildly obsolete;
    they were made to my master manuscripts years ago but have, alas,
    never seen the light of day until now.

    Because of some overly ambitious formatting changes I've embarked on,
    the updated HTML version is *still* not quite ready. But the light
    at the end of the tunnel is in sight: that grandish unveiling will
    happen in the next month or so.

    I've categorized the diffs that follow into brand-new questions,
    significant changes, minor adjustments, and (sob!) retired questions.
    The notation is based on that of the standard `diff' program: `<'
    indicates old, changed, or deleted text; `>' indicates new text.
    (For my fellow packrats out there: don't worry, the deleted
    questions, and most of the other deleted text, will live on
    in the web version...)


    First, the new questions. (Some of these are migrated from the
    book-length version, but most of them are brand new.)

    ==========

    > 2.4b: Is there a good way of simulating OOP-style inheritance, or
    > other OOP features, in C?
    >
    > A: It's straightforward to implement simple "methods" by placing
    > function pointers in structures. You can make various clumsy,
    > brute-force attempts at inheritance using the preprocessor or by
    > having structures contain "base types" as initial subsets, but
    > it won't be perfect. There's obviously no operator overloading,
    > and overriding (i.e. of "methods" in "derived classes") would
    > have to be done by hand.
    >
    > Obviously, if you need "real" OOP, you'll want to use a language
    > that supports it, such as C++.


    ==========

    > 3.12a: What's the difference between ++i and i++?
    >
    > A: If your C book doesn't explain, get a better one. Briefly:
    > ++i adds one to the stored value of i and "returns" the new,
    > incremented value to the surrounding expression; i++ adds one
    > to i but returns the prior, unincremented value.


    ==========

    > 4.15: How do I convert an int to a char *? I tried a cast, but it's
    > not working.
    >
    > A: It depends on what you're trying to do. If you tried a cast
    > but it's not working, you're probably trying to convert an
    > integer to a string, in which case see question 13.1. If you're
    > trying to convert an integer to a character, see question 8.6.
    > If you're trying to set a pointer to point to a particular
    > memory address, see question 19.25.


    ==========

    > 7.7c: In a call to malloc(), what does an error like "Cannot convert
    > `void *' to `int *'" mean?
    >
    > A: It means you're using a C++ compiler instead of a C compiler.
    > See question 7.7.


    ==========

    > 7.11: How can I dynamically allocate arrays?
    >
    > A: See questions 6.14 and 6.16.


    ==========

    > 11.8b: If you can't modify string literals, why aren't they defined as
    > being arrays of const characters?
    >
    > A: One reason is that so very much code contains lines like
    >
    > char *p = "Hello, world!";
    >
    > which are not necessarily incorrect. These lines would suffer
    > the diagnostic messages, but it's really any later attempt to
    > modify what p points to which would be problems.
    >
    > See also question 1.32.


    ==========

    > 11.14b: So what could go wrong? Are there really any systems where
    > void main() doesn't work?
    >
    > A: It has been reported that programs using void main() and
    > compiled using BC++ 4.5 can crash. Some compilers (including
    > DEC C V4.1 and gcc with certain warnings enabled) will complain
    > about void main().


    ==========

    > 11.33b: What does it really mean for a program to be "legal" or "valid"
    > or "conforming"?
    >
    > A: Simply stated, the Standard talks about three kinds of
    > conformance: conforming programs, strictly conforming programs,
    > and conforming implementations.
    >
    > A "conforming program" is one that is accepted by a conforming
    > implementation.
    >
    > A "strictly conforming program" is one that uses the language
    > exactly as specified in the Standard, and that does not depend
    > on any implementation-defined, unspecified, or undefined
    > behavior.
    >
    > A "conforming implementation" is one that does everything the
    > Standard says it's supposed to.
    >
    > References: ISO Sec. ; Rationale Sec. 1.7.


    ==========

    > 12.1b: I have a simple little program that reads characters until EOF,
    > but how do I actually *enter* that "EOF" value from the
    > keyboard?
    >
    > A: It turns out that the value of EOF as seen within your C program
    > has essentially nothing to do with the keystroke combination you
    > might use to signal end-of-file from the keyboard. Depending on
    > your operating system, you indicate end-of-file from the
    > keyboard using various keystroke combinations, usually either
    > control-D or control-Z.


    ==========

    > 12.12b: Why *does* the call
    >
    > char s[30];
    > scanf("%s", s);
    >
    > work (without the &)?
    >
    > A: You always need a *pointer*; you don't necessarily need an
    > explicit &. When you pass an array to scanf(), you do not need
    > the &, because arrays are always passed to functions as
    > pointers, whether you use & or not. See questions 6.3 and 6.4.


    ==========

    > 12.26b: If fflush() won't work, what can I use to flush input?
    >
    > A: It depends on what you're trying to do. If you're trying to get
    > rid of an unread newline or other unexpected input after calling
    > scanf() (see questions 12.18a-12.19), you really need to rewrite
    > or replace the call to scanf() (see question 12.20).
    > Alternatively, you can consume the rest of a partially-read line
    > with a simple code fragment like
    >
    > while((c = getchar()) != '\n' && c != EOF)
    > /* discard */ ;
    >
    > (You may also be able to use the curses flushinp() function.)


    ==========

    > 12.27: fopen() is failing for certain pathnames.
    >
    > A: See questions 19.17 and 19.17b.


    ==========

    > 13.29: My compiler is complaining that printf is undefined!
    > How can this be?
    >
    > A: Allegedly, there are C compilers for Microsoft Windows which do
    > not support printf(). It may be possible to convince such a
    > compiler that what you are writing is a "console application"
    > meaning that it will open a "console window" in which printf()
    > is supported.


    ==========

    > 17.4b: I've seen function declarations that look like this:
    >
    > extern int func __((int, int));
    >
    > What are those extra parentheses and underscores for?
    >
    > A: They're part of a trick which allows the prototype part of the
    > function declaration to be turned off for a pre-ANSI compiler.
    > Somewhere else is a conditional definition of the __ macro like
    > this:
    >
    > #ifdef __STDC__
    > #define __(proto) proto
    > #else
    > #define __(proto) ()
    > #endif
    >
    > The extra parentheses in the invocation
    >
    > extern int func __((int, int));
    >
    > are required so that the entire prototype list (perhaps
    > containing many commas) is treated as the single argument
    > expected by the macro.


    ==========

    > 18.9b: Where can I find some good code examples to study and learn
    > from?
    >
    > A: Here are a couple of links to explore:
    >
    > ftp://garbo.uwasa.fi/pc/c-lang/00index.txt
    >
    > http://www.eskimo.com/~scs/src/
    >
    > (Beware, though, that there is all too much truly bletcherous
    > code out there, too. Don't "learn" from bad code that it's the
    > best anyone can do; you can do better.) See also questions
    > 18.9, 18.13, 18.15c, and 18.16.


    ==========

    > 19.9b: How can I access an I/O board directly?
    >
    > A: In general, there are two ways to do this: use system-specific
    > functions such as "inport" and "outport" (if the device is
    > accessed via an "I/O port"), or use contrived pointer variables
    > to access "memory-mapped I/O" device locations. See question
    > 19.25.


    ==========

    > 19.10b: How can I display GIF and JPEG images?
    >
    > A: It will depend on your display environment, which may already
    > provide these functions. Reference JPEG software is at
    > http://www.ijg.org/files/ .


    ==========

    > 19.17b: fopen() isn't letting me open files like "$HOME/.profile" and
    > "~/.myrcfile".
    >
    > A: Under Unix, at least, environment variables like $HOME, along
    > with the home-directory notation involving the ~ character, are
    > expanded by the shell, and there's no mechanism to perform these
    > expansions automatically when you call fopen().


    ==========

    > 19.17c: How can I suppress the dreaded MS-DOS "Abort, Retry, Ignore?"
    > message?
    >
    > A: Among other things, you need to intercept the DOS Critical Error
    > Interrupt, interrupt 24H. See the comp.os.msdos.programmer FAQ
    > list for more details.


    ==========

    > 19.40d: What are "near" and "far" pointers?
    >
    > A: These days, they're pretty much obsolete; they're definitely
    > system-specific. If you really need to know, see a DOS- or
    > Windows-specific programming reference.


    ==========

    > 20.9b: How do I swap bytes?
    >
    > A: V7 Unix had a swab() function, but it seems to have been
    > forgotten.
    >
    > A problem with explicit byte-swapping code is that you have
    > to decide whether to call it or not; see question 20.9 above.
    > A better solution is to use functions (such as the BSD
    > networking ntohs() et al.) which convert between the known byte
    > order of the data and the (unknown) byte order of the machine,
    > and to arrange for these functions to be no-ops on those
    > machines which already match the desired byte order.
    >
    > If you do have to write your own byte-swapping code, the two
    > obvious approaches are again to use pointers or unions, as in
    > question 20.9.
    >
    > References: PCS Sec. 11 p. 179.


    ====================


    Next, here are the significant changes.

    ==========

    [Q1.1 How should I decide which integer type to use?]

    If for some reason you need to declare something with an
    *exact* size... be sure to encapsulate the choice behind
    < an appropriate typedef.
    ---
    > an appropriate typedef, such as those in C99's <inttypes.h>.


    > If you need to manipulate huge values, larger than the
    > guaranteed range of C's built-in types, see question 18.15d.


    ==========

    [Q1.4 What should the 64-bit type be on a machine that can support it?]

    < A: The forthcoming revision to the C Standard (C9X) specifies type
    < long long as effectively being at least 64 bits, and this type
    < has been implemented by a number of compilers for some time.
    < (Others have implemented extensions such as __longlong.)
    < On the other hand, there's no theoretical reason why a compiler
    < couldn't implement type short int as 16, int as 32, and long int
    < as 64 bits, and some compilers do indeed choose this
    < arrangement.
    ---
    > A: The new C99 Standard specifies type long long as effectively
    > being at least 64 bits, and this type has been implemented by a
    > number of compilers for some time. (Others have implemented
    > extensions such as __longlong.) On the other hand, it's also
    > appropriate to implement type short int as 16, int as 32, and
    > long int as 64 bits, and some compilers do.


    ==========

    [Q1.7 What's the best way to declare and define global variables...]

    A: First, though there can be many "declarations" (and in many
    < translation units) of a single "global" (strictly speaking,
    < "external") variable or function, there must be exactly one
    < "definition". (The definition is the declaration that actually
    < allocates space, and provides an initialization value, if any.)
    ---
    > translation units) of a single global variable or function,
    > there must be exactly one "definition", where the definition is
    > the declaration that actually allocates space, and provides an
    > initialization value, if any.


    ==========

    (Unix compilers and linkers typically use a "common model" which
    allows multiple definitions, as long as at most one is
    initialized; this behavior is mentioned as a "common extension"
    < by the ANSI Standard, no pun intended. A few very odd systems
    < may require an explicit initializer to distinguish a definition
    < from an external declaration.)
    ---
    > by the ANSI Standard, no pun intended.)


    ==========

    [Q1.25 My compiler is complaining about an invalid redeclaration...]

    < A: Functions which are called without a declaration in scope
    < (perhaps because the first call precedes the function's
    < definition) are assumed to be declared as returning int (and
    without any argument type information), leading to discrepancies
    < if the function is later declared or defined otherwise. Non-int
    < functions must be declared before they are called.
    ---
    > A: Functions which are called without a declaration in scope,
    > perhaps because the first call precedes the function's
    > definition, are assumed to be declared as returning int (and

    without any argument type information), leading to discrepancies
    > if the function is later declared or defined otherwise. All
    > functions should be (and non-int functions must be) declared
    > before they are called.


    ==========

    [Q1.30 What am I allowed to assume about the initial values...]

    > These rules do apply to arrays and structures (termed
    > "aggregates"); arrays and structures are considered "variables"
    > as far as initialization is concerned.


    ==========

    [Q1.31 This code, straight out of a book, isn't compiling]

    < A: Perhaps you have a pre-ANSI compiler, which doesn't allow
    < initialization of "automatic aggregates" (i.e. non-static
    < local arrays, structures, and unions). (As a workaround, and
    < depending on how the variable a is used, you may be able to make
    < it global or static, or replace it with a pointer, or initialize
    < it by hand with strcpy() when f() is called.)
    ---
    > A: Perhaps you have an old, pre-ANSI compiler, which doesn't allow
    > initialization of "automatic aggregates" (i.e. non-static local
    > arrays, structures, or unions).


    ==========

    [Q1.34 I finally figured out the syntax for... pointers to functions...]

    < An explicit declaration for the function is normally needed,
    < since implicit external function declaration does not happen in
    < this case (because the function name in the initialization is
    < not part of a function call).
    ---
    > A prior, explicit declaration for the function (perhaps in a
    > header file) is normally needed. The implicit external function
    > declaration that can occur when a function is called does not
    > help when a function name's only use is for its value.


    ==========

    [Q2.4 How can I implement opaque (abstract) data types in C?]

    A: One good way is for clients to use structure pointers (perhaps
    additionally hidden behind typedefs) which point to structure
    > types which are not publicly defined. It's legal to declare
    > and use "anonymous" structure pointers (that is, pointers to
    > structures of incomplete type), as long as no attempt is made to
    > access the members -- which of course is exactly the point of an
    > opaque type.


    ==========

    [Q2.6 I came across some code that declared a structure like this...]

    these "chummy" structures must be used with care, since the
    programmer knows more about their size than the compiler does.
    < (In particular, they can generally only be manipulated via
    < pointers.)

    < C9X will introduce the concept of a "flexible array member",
    < which will allow the size of an array to be omitted if it is
    < the last member in a structure, thus providing a well-defined
    < solution.
    ---
    > C99 introduces the concept of a "flexible array member", which
    > allows the size of an array to be omitted if it is the last
    > member in a structure, thus providing a well-defined solution.


    ==========

    [Q2.10 How can I pass constant... structure arguments?]

    < A: As of this writing, C has no way of generating anonymous
    < structure values. You will have to use a temporary structure
    < variable or a little structure-building function.
    ---
    > A: Traditional C had no way of generating anonymous structure
    > values; you had to use a temporary structure variable or a
    > little structure-building function.


    < The C9X Standard will introduce "compound literals"; one form of
    < compound literal will allow structure constants. For example,
    < to pass a constant coordinate pair to a plotpoint() function
    < which expects a struct point, you will be able to call
    ---
    > C99 introduces "compound literals", one form of which provides
    > for structure constants. For example, to pass a constant
    > coordinate pair to a hypothetical plotpoint() function which
    > expects a struct point, you can call


    < Combined with "designated initializers" (another C9X feature),
    < it will also be possible to specify member values by name:
    ---
    > Combined with "designated initializers" (another C99 feature),
    > it is also possible to specify member values by name:


    ==========

    2.12: My compiler is leaving holes in structures, which is wasting
    < space and preventing "binary" I/O to external data files. Can I
    < turn off the padding, or otherwise control the alignment of
    ---
    > space and preventing "binary" I/O to external data files. Why?
    > Can I turn this off, or otherwise control the alignment of


    < A: Your compiler may provide an extension to give you this control
    < (perhaps a #pragma; see question 11.20), but there is no
    < standard method.
    ---
    > A: Those "holes" provide "padding", which may be needed in order to
    > preserve the "alignment" of later fields of the structure. For
    > efficient access, most processors prefer (or require) that
    > multibyte objects (e.g. structure members of any type larger
    > than char) not sit at arbitrary memory addresses, but rather at
    > addresses which are multiples of 2 or 4 or the object size.
    >
    > Your compiler may provide an extension to give you explicit
    > control over struct alignment (perhaps involving a #pragma; see
    > question 11.20), but there is no standard method.


    ==========

    [Q2.14 How can I determine the byte offset of a field within a structure?]

    < A: ANSI C defines the offsetof() macro, which should be used if
    < available; see <stddef.h>. If you don't have it, one possible
    < implementation is
    ---
    > A: ANSI C defines the offsetof() macro in <stddef.h>, which lets
    > you compute the offset of field f in struct s as
    > offsetof(struct s, f). If for some reason you have to code this
    > sort of thing yourself, one possibility is


    ==========

    [2.15 How can I access structure fields by name at run time?]

    < A: Build a table of names and offsets, using the offsetof() macro.
    < The offset of field b in struct a is
    <
    < offsetb = offsetof(struct a, b)
    <
    < If structp is a pointer to an instance of this structure, and
    < field b is an int (with offset as computed above), b's value can
    < be set indirectly with
    ---
    > A: Keep track of the field offsets as computed using the offsetof()
    > macro (see question 2.14). If structp is a pointer to an
    > instance of the structure, and field f is an int having offset
    > offsetf, f's value can be set indirectly with


    ==========

    [Q2.20 Can I initialize unions?]

    < A: The current C Standard allows an initializer for the first-named
    < member of a union. C9X will introduce "designated initializers"
    < which can be used to initialize any member.
    ---
    > A: In the original ANSI C, an initializer was allowed only for the
    > first-named member of a union. C99 introduces "designated
    > initializers" which can be used to initialize any member.


    ==========

    [Q3.2 Under my compiler... Regardless of the order of evaluation...]

    example, the compiler chose to multiply the previous value by
    < itself and to perform both increments afterwards.
    ---
    > itself and to perform both increments later.


    [Q3.8 How can I understand these complex expressions?]

    The second sentence can be difficult to understand. It says
    that if an object is written to within a full expression, any
    < and all accesses to it within the same expression must be for
    < the purposes of computing the value to be written. This rule
    effectively constrains legal expressions to those in which the
    accesses demonstrably precede the modification.
    ---
    > and all accesses to it within the same expression must be
    > directly involved in the computation of the value to be written.

    This rule effectively constrains legal expressions to those in
    > which the accesses demonstrably precede the modification. For
    > example, i = i + 1 is legal, but not a = i++ (see question
    > 3.1).


    ==========

    [3.9 So... we don't know which..., but i does get incremented..., right?]

    < A: *No*. Once an expression or program becomes undefined, *all*
    ---
    > A: Not necessarily! Once an expression or program becomes

    undefined, *all* aspects of it become undefined.

    ==========

    [Q4.2 I'm trying to declare a pointer and allocate some space for it...]

    < A: The pointer you declared is p, not *p. To make a pointer point
    < somewhere, you just use the name of the pointer:
    ---
    > A: The pointer you declared is p, not *p. When you're manipulating
    > the pointer itself (for example when you're setting it to make
    > it point somewhere), you just use the name of the pointer:


    ==========

    [4.3 Does *p++ increment p, or what it points to?]

    < A: Postfix ++ essentially has higher precedence than the prefix
    ---
    > A: The postfix ++ and -- operators essentially have higher

    precedence than the prefix unary operators.

    ==========

    [Q4.10 ...How can I pass a constant by reference?]

    < A: You can't do this directly. You will have to declare
    ---
    > A: In C99, you can use a "compound literal":
    >
    > f((int[]){5});
    >
    > Prior to C99, you couldn't do this directly; you had to declare

    a temporary variable, and then pass its address to the function:

    ==========

    [Q5.6 If NULL were defined as follows...]

    > At any rate, ANSI function prototypes ensure that most (though
    > not quite all; see question 5.2) pointer arguments are converted
    > correctly when passed as function arguments, so the question is
    > largely moot.


    ==========

    5.20: What does a run-time "null pointer assignment" error mean?
    < How can I track it down?

    < A debugger may let you set a data watchpoint on location 0.
    < Alternatively, you could write a bit of code to stash away a
    < copy of 20 or so bytes from location 0, and periodically check
    < that the memory at location 0 hasn't changed. See also question
    < 16.8.

    ==========

    [Q6.15 How can I declare local arrays of a size matching a passed-in array?]

    < A: Until recently, you couldn't. Array dimensions in C
    < traditionally had to be compile-time constants. C9X will
    < introduce variable-length arrays (VLA's) which will solve this
    ---
    > A: Until recently, you couldn't; array dimensions in C
    > traditionally had to be compile-time constants. However, C99
    > introduces variable-length arrays (VLA's) which solve this

    problem; local arrays may have sizes set by variables or other
    expressions, perhaps involving function parameters.

    ==========

    [Q6.16 How can I dynamically allocate a multidimensional array?]

    > You can also use sizeof(*array1) and sizeof(**array1)
    > instead of sizeof(int *) and sizeof(int).)


    ==========

    [Q6.19 How do I write functions which accept two-dimensional arrays...]

    < C9X will allow variable-length arrays, and once compilers which
    < accept C9X's extensions become widespread, this will probably
    ---
    > C99 allows variable-length arrays, and once compilers which
    > accept C99's extensions become widespread, VLA's will probably

    become the preferred solution.

    ==========

    [Q7.27 So can I query the malloc package to find out how big...]

    > (Some compilers provide nonstandard extensions.)


    ==========

    [Q7.32 What is alloca() and why is its use discouraged?]

    > Now that C99 supports variable-length arrays (VLA's),
    > they can be used to more cleanly accomplish most of the
    > tasks which alloca() used to be put to.


    ==========

    [Q8.6 How can I get the numeric (character set) value corresponding to...]

    > To convert back and forth between the digit characters and the
    > corresponding integers in the range 0-9, add or subtract the
    > constant '0' (that is, the character value '0').


    ==========

    [Q10.7 Is it acceptable for one header file to #include another?]

    the prestigious Indian Hill Style Guide (see question 17.9)
    disparages them; they can make it harder to find relevant
    definitions; they can lead to multiple-definition errors if a file
    < is #included twice;
    ---
    > is #included twice; they can lead to increased compilation time;

    and they make manual Makefile maintenance very difficult.

    ==========

    < 10.11: I seem to be missing the system header file <sgtty.h>.
    < Can someone send me a copy?
    ---
    > 10.11: I'm compiling a program, and I seem to be missing one of the
    > header files it requires. Can someone send me a copy?


    > A: There are several situations, depending on what sort of header
    > file it is that's "missing".
    >
    > If the missing header file is a standard one, there's a problem
    > with your compiler. You'll need to contact your vendor, or
    > someone knowledgeable about your particular compiler, for help.
    >
    > The situation is more complicated in the case of nonstandard
    > headers. Some are completely system- or compiler-specific.
    > Some are completely unnecessary, and should be replaced by their
    > Standard equivalents. (For example, instead of <malloc.h>, use
    > <stdlib.h>.) Other headers, such as those associated with
    > popular add-on libraries, may be reasonably portable.


    Standard headers exist in part so that definitions appropriate
    to your compiler, operating system, and processor can be
    supplied. You cannot just pick up a copy of someone else's
    header file and expect it to work, unless that person is using
    < exactly the same environment. Ask your compiler vendor why the
    < file was not provided (or to send a replacement copy).
    ---
    > exactly the same environment. You may actually have a
    > portability problem (see section 19), or a compiler problem.
    > Otherwise, see question 18.16.


    ==========

    [Q10.26 How can I write a macro which takes a variable number of arguments?]

    < C9X will introduce formal support for function-like macros with
    < variable-length argument lists. The notation ... will appear at
    ---
    > C99 introduces formal support for function-like macros with
    > variable-length argument lists. The notation ... can appear at


    < definition will be replaced by the variable arguments during
    ---
    > definition is replaced by the variable arguments during


    ==========

    [Q11.1 What is the "ANSI C Standard?"]

    < More recently, the Standard has been adopted as an international
    < standard, ISO/IEC 9899:1990, and this ISO Standard replaces the
    < earlier X3.159 even within the United States (where it is known
    ---
    > A year or so later, the Standard was adopted as an international
    > standard, ISO/IEC 9899:1990, and this ISO Standard replaced the
    > earlier X3.159 even within the United States (where it was known


    < As of this writing, a complete revision of the Standard is in
    < its final stages. The new Standard is nicknamed "C9X" on the
    < assumption that it will be finished by the end of 1999. (Many
    < of this article's answers have been updated to reflect new C9X
    < features.)
    ---
    > Most recently, a major revision of the Standard, "C99", has been
    > completed and adopted.


    < The original ANSI Standard included a "Rationale," explaining
    < many of its decisions, and discussing a number of subtle points,
    < including several of those covered here. (The Rationale was
    < "not part of ANSI Standard X3.159-1989, but... included for
    < information only," and is not included with the ISO Standard.
    < A new one is being prepared for C9X.)
    ---
    > Several versions of the Standard, including C99 and the original
    > ANSI Standard, have included a "Rationale," explaining many of
    > its decisions, and discussing a number of subtle points,
    > including several of those covered here.


    ==========

    [Q11.2 How can I get a copy of the Standard?]

    < Note that ANSI derives revenues to support its operations
    < from the sale of printed standards, so electronic copies
    < are *not* available.
    ---
    > An electronic (PDF) copy is available on-line, for US$18,
    > from www.ansi.org.


    < The last time I checked, the cost was $130.00 from ANSI or
    < $400.50 from Global. Copies of the original X3.159 (including
    < the Rationale) may still be available at $205.00 from ANSI or
    < $162.50 from Global.

    < In the U.S., it may be possible to get a copy of the original
    < ANSI X3.159 (including the Rationale) as "FIPS PUB 160" from
    <
    < National Technical Information Service (NTIS)
    < U.S. Department of Commerce
    < Springfield, VA 22161
    < 703 487 4650

    ==========

    [Q11.10 Why can't I pass a char ** to a function which expects...]

    < You must use explicit casts (e.g. (const char **) in this case)
    < when assigning (or passing) pointers which have qualifier
    < mismatches at other than the first level of indirection.
    ---
    > If you must assign or pass pointers which have qualifier
    > mismatches at other than the first level of indirection, you
    > must use explicit casts (e.g. (const char **) in this case),
    > although as always, the need for such a cast may indicate a
    > deeper problem which the cast doesn't really fix.


    ==========

    < 11.27: Why does the ANSI Standard not guarantee more than six case-
    < insensitive characters of external identifier significance?
    ---
    > 11.27: Why does the ANSI Standard place limits on the length and case-
    > significance of external identifiers?


    The limitation is only that identifiers be *significant*
    < in the first six characters, not that they be restricted to
    < six characters in length. This limitation is marked in the
    < Standard as "obsolescent", and will be removed in C9X.
    ---
    > in some initial sequence of characters, not that they be
    > restricted to that many characters in total length.
    > (The limitation was to six characters in the original
    > ANSI Standard, but has been relaxed to 31 in C99.)


    ==========

    [Q11.33 ...implementation-defined, unspecified, and undefined behavior.]

    > (A fourth defined class of not-quite-precisely-defined behavior,
    > without the same stigma attached to it, is "locale-specific".)


    ==========

    [Q12.2 Why does the code... copy the last line twice?]

    Usually, you should just check the return value of
    < the input routine (in this case, fgets() will return NULL on end-
    < of-file); often, you don't need to use feof() at all.
    ---
    > the input routine -- fgets(), for example, returns NULL on end-
    > of-file. In virtually all cases, there's no need to use feof()
    > at all.


    ==========

    [Q12.21 How can I tell how much... buffer space... for a... sprintf call?]

    < The "obvious" solution to the overflow problem is a length-
    < limited version of sprintf(), namely snprintf(). It would be
    < used like this:
    ---
    > To avoid the overflow problem, you can use a length-limited
    > version of sprintf(), namely snprintf(). It is used like this:


    < It will be standardized in C9X.
    ---
    > It has finally been standardized in C99.


    < When the C9X snprintf() arrives, it will also be possible to use
    < it to predict the size required for an arbitrary sprintf() call.
    < C9X snprintf() will return the number of characters it would
    < have placed in the buffer, not just how many it did place.
    < Furthermore, it may be called with a buffer size of 0 and a
    < null pointer as the destination buffer. Therefore, the call
    ---
    > As an extra, added bonus, the C99 snprintf() provides a way
    > to predict the size required for an arbitrary sprintf() call.
    > C99's snprintf() returns the number of characters it would have
    > placed in the buffer, and it may be called with a buffer size
    > of 0. Therefore, the call


    < will compute the number of characters required for the fully-
    ---
    > predicts the number of characters required for the fully-


    > Yet another option is the (nonstandard) asprintf() function,
    > present in various C libraries including bsd's and GNU's, which
    > formats to (and returns a pointer to) a malloc'ed buffer, like
    > this:
    >
    > char *buf;
    > asprintf(&buf, "%d = %s", 42, "forty-two");
    > /* now buf points to malloc'ed space containing formatted string */


    ==========

    [Q12.23 Why does everyone say not to use gets()?]

    A: Unlike fgets(), gets() cannot be told the size of the buffer
    it's to read into, so it cannot be prevented from overflowing
    < that buffer. As a general rule, always use fgets().
    ---
    > that buffer. The Standard fgets() function is a vast
    > improvement over gets(), although it's not perfect, either.
    > (If long lines are a real possibility, their proper handling
    > must be carefully considered.)


    ==========

    < 12.26: How can I flush pending input so that a user's typeahead isn't
    ---
    > 12.26b: If fflush() won't work, what can I use to flush input?


    There is no standard way to discard unread characters from a
    stdio input stream, nor would such a way necessarily be
    sufficient, since unread characters can also accumulate in
    < other, OS-level input buffers. You may be able to read and
    < discard characters until \n, or use the curses flushinp()
    < function, or use some system-specific technique. See also
    < questions 19.1 and 19.2.
    ---
    > other, OS-level input buffers. If you're trying to actively
    > discard typed-ahead input (perhaps in anticipation of issuing a
    > critical prompt), you'll have to use a system-specific
    > technique; see questions 19.1 and 19.2.


    ==========

    [Q12.30 I'm trying to update a file in place...]

    writing in the read/write "+" modes. Also, remember that you
    can only overwrite characters with the same number of
    replacement characters, and that overwriting in text mode may
    < truncate the file at that point. See also question 19.14.
    ---
    > truncate the file at that point, and that you may have to
    > preserve line lengths. See also question 19.14.


    ==========

    [Q12.34 Once I've used freopen(), how can I get the original stdout... back?]

    < It is barely possible to save away information about a stream
    < before calling freopen(), such that the original stream can
    < later be restored, but the methods involve system-specific calls
    < such as dup(), or copying or inspecting the contents of a FILE
    < structure, which is exceedingly nonportable and unreliable.
    ---
    > It may be possible, in a nonportable way, to save away
    > information about a stream before calling freopen(), such that
    > the original stream can later be restored. One way is to use a
    > system-specific call such as dup() or dup2(), if available.
    > Another is to copy or inspect the contents of the FILE
    > structure, but this is exceedingly nonportable and unreliable.


    ==========

    12.36b: How can I arrange to have output go two places at once,
    e.g. to the screen and to a file?

    > Here is a simple example:
    >
    > #include <stdio.h>
    > #include <stdarg.h>
    >
    > void f2printf(FILE *fp1, FILE *fp2, char *fmt, ...)
    > {
    > va_list argp;
    > va_start(argp, fmt); vfprintf(fp1, fmt, argp); va_end(argp);
    > va_start(argp, fmt); vfprintf(fp2, fmt, argp); va_end(argp);
    > }
    >
    > where f2printf() is just like fprintf() except that you give it
    > two file pointers and it prints to both of them.


    ==========

    [Q13.2 Why does strncpy() not always place a '\0' terminator...]

    You can get around the problem by using strncat() instead
    of strncpy(): if the destination string starts out empty
    > (that is, if you do *dest = '\0' first), strncat()

    does what you probably wanted strncpy() to do.

    ==========

    [Q13.12 How can I get the current date or time of day in a C program?]

    < printf("It's %.24s.\n", ctime(&now));
    ---
    > printf("It's %s", ctime(&now));


    > If you need control over the format, use strftime().
    > If you need sub-second resolution, see question 19.37.


    ==========

    [Q13.14 How can I add N days to a date?]

    A: The ANSI/ISO Standard C mktime() and difftime() functions
    < provide some support for both problems.
    ---
    > provide some (limited) support for both problems.


    < These solutions are only guaranteed to work correctly
    ---
    > However, these solutions are guaranteed to work correctly only

    for dates in the range which can be represented as time_t's.

    > (For conservatively-sized time_t, that range is often -- but not
    > always -- from 1970 to approximately 2037; note however that
    > there are time_t representations other than as specified by Unix
    > and Posix.)


    Another approach to both problems,
    > which will work over a much wider range of dates,

    is to use "Julian day numbers".

    ==========

    [Q13.15 I need a random number generator.]

    If you do find yourself needing to implement your own random
    number generator, there is plenty of literature out there; see
    < the References. There are also any number of packages on the
    < net: look for r250, RANLIB, and FSULTRA (see question 18.16).
    ---
    > the References below or the sci.math.num-analysis FAQ list.
    > There are also any number of packages on the net: old standbys
    > are r250, RANLIB, and FSULTRA (see question 18.16), and there is
    > much recent work by Marsaglia, and Matumoto and Nishimura (the
    > "Mersenne Twister"), and some code collected by Don Knuth on his
    > web pages.


    ==========

    [Q13.17 Each time I run my program, I get the same sequence of numbers...]

    A: You can call srand() to seed the pseudo-random number generator
    < with a truly random initial value. Popular seed values are the
    < time of day, or the elapsed time before the user presses a key
    < (although keypress times are hard to determine portably;
    ---
    > with a truly random (or at least variable) initial value, such
    > as the time of day. Here is a simple example:
    >
    > #include <stdlib.h>
    > #include <time.h>
    >
    > srand((unsigned int)time((time_t *)NULL));
    >
    > (Unfortunately, this code isn't perfect -- among other things,
    > the time_t returned by time() might be a floating-point type,
    > hence not portably convertible to unsigned int without the
    > possibility of overflow.


    ==========

    [Q14.1 When I set a float... 3.1, why is printf printing it as 3.0999999?]

    A: Most computers use base 2 for floating-point numbers as well as
    < for integers. In base 2, one divided by ten is an infinitely-
    < repeating fraction (0.0001100110011...), so fractions such as
    < 3.1 (which look like they can be exactly represented in decimal)
    ---
    > for integers. Although 0.1 is a nice, polite-looking fraction
    > in base 10, its base-2 representation is an infinitely-repeating
    > fraction (0.0001100110011...), so exact decimal fractions such as 3.1

    cannot be represented exactly in binary.

    [Q14.3 ...I keep getting "undefined: sin" compilation errors.]

    A: Make sure you're actually linking with the math library. For
    < instance, under Unix, you usually need to use the -lm option, at
    ---
    > instance, due to a longstanding bug in Unix and Linux systems,
    > you usually need to use an explicit -lm flag, at the *end* of

    the command line, when compiling/linking.

    ==========

    [Q14.5 What's a good way to check for "close enough" floating-point equality?]

    use something like

    #include <math.h>
    if(fabs(a - b) <= epsilon * fabs(a))

    < for some suitably-chosen degree of closeness epsilon (as long as
    < a is nonzero!).
    ---
    > where epsilon is a value chosen to set the degree of "closeness"
    > (and where you know that a will not be zero).


    ==========

    [Q14.8 The predefined constant M_PI seems to be missing...]
    machine's copy of <math.h>.

    If you need pi, you'll have to define it yourself, or compute it
    < with 4*atan(1.0).
    ---
    > with 4*atan(1.0) or acos(-1.0).


    ==========

    [Q14.9 How do I test for IEEE NaN and other special values?]

    < C9X will provide isnan(), fpclassify(), and several other
    ---
    > C99 provides isnan(), fpclassify(), and several other

    classification routines.

    ==========

    [Q14.11 What's a good way to implement complex numbers in C?]

    < C9X will support complex as a standard type.
    ---
    > C99 supports complex as a standard type.


    ==========

    [Q15.6 How can I write a function analogous to scanf()...]

    < A: C9X will support vscanf(), vfscanf(), and vsscanf().
    < (Until then, you may be on your own.)
    ---
    > A: C99 (but *not* any earlier C Standard) supports vscanf(),
    > vfscanf(), and vsscanf().


    ==========

    [Q16.1b I'm getting baffling syntax errors which make no sense at all...]

    < A: Check for unclosed comments or mismatched #if/#ifdef/#ifndef/
    < #else/#endif directives; remember to check header files, too.
    ---
    > A: Check for unclosed comments, mismatched #if/#ifdef/#ifndef/
    > #else/#endif directives, and perhaps unclosed quotes; remember

    to check header files, too.

    [Section 18. Tools and Resources]

    > [NOTE: Much of the information in this section is fairly old and may be
    > out-of-date, especially the URLs of various allegedly publicly-available
    > packages. Caveat lector.]


    ==========

    [Q18.1 I need...]

    tools to compute code ccount, Metre, lcount, or csize,
    < metrics or see URL http://www.qucis.queensu.ca/
    < Software-Engineering/Cmetrics.html ;
    ---
    > tools to compute code ccount, Metre, lcount, or csize;

    metrics there is also a package sold by
    McCabe and Associates

    ==========

    [Q18.2 How can I track down these pesky malloc problems?]

    < MEMDEBUG from ftp.crpht.lu in pub/sources/memdebug .
    ---
    > MEMDEBUG from ftp.crpht.lu in pub/sources/memdebug ; and
    > Electric Fence.


    < Bounds-Checker for DOS, from Nu-Mega Technologies,
    < P.O. Box 7780, Nashua, NH 03060-7780, USA, 603-889-2386.

    CodeCenter (formerly Saber-C) from Centerline Software,
    < 10 Fawcett Street, Cambridge, MA 02138, USA, 617-498-3000.
    ---
    > (http://www.centerline.com/).


    < Insight, from ParaSoft Corporation, 2500 E. Foothill
    < Blvd., Pasadena, CA 91107, USA, 818-792-9941,
    < .
    ---
    > Insight (now Insure?), from ParaSoft Corporation
    > (http://www.parasoft.com/).


    < Purify, from Pure Software, 1309 S. Mary Ave., Sunnyvale,
    < CA 94087, USA, 800-224-7873, http://www.pure.com ,
    < .
    < (I believe Pure was recently acquired by Rational.)
    ---
    > Purify, from Rational Software (http://www-
    > 306.ibm.com/software/rational/, formerly Pure Software,
    > now part of IBM).


    < Final Exam Memory Advisor, from PLATINUM Technology
    < (formerly Sentinel from AIB Software), 1815 South Meyers
    < Rd., Oakbrook Terrace, IL 60181, USA, 630-620-5000,
    < 800-442-6861, , www.platinum.com .

    < ZeroFault, from The Kernel Group, 1250 Capital of Texas
    < Highway South, Building Three, Suite 601, Austin,
    < TX 78746, 512-433-3333, http://www.tkg.com, .
    ---
    > ZeroFault, from The ZeroFault Group,
    > http://www.zerofault.com/.


    ==========

    [Q18.3 What's a free or cheap C compiler I can use?]

    < compiler, or gcc. It is available by anonymous ftp from
    < prep.ai.mit.edu in directory pub/gnu, or at several other FSF
    < archive sites.
    ---
    > compiler, or gcc; see the gcc home page at http://gcc.gnu.org/.


    < There are currently no viable shareware compilers for the
    < Macintosh.
    ---
    > As far as I know, there
    > are versions of gcc for Macs and Windows machines, too.


    < There is a shareware compiler called PCC, available as
    < PCC12C.ZIP .

    < Another recently-developed compiler is lcc, available for
    < anonymous ftp from ftp.cs.princeton.edu in pub/lcc/.
    ---
    > Another popular compiler is lcc, described at
    > http://www.cs.virginia.edu/~lcc-win32/ and
    > http://www.cs.princeton.edu/software/lcc/.


    < Archives associated with comp.compilers contain a great deal of
    < information about available compilers, interpreters, grammars,
    < etc. (for many languages). The comp.compilers archives
    < (including an FAQ list), maintained by the moderator, John R.
    < Levine, are at iecc.com . A list of available compilers and
    < related resources, maintained by Mark Hopkins, Steven Robenalt,
    < and David Muir Sharnoff, is at ftp.idiom.com in pub/compilers-
    < list/. (See also the comp.compilers directory in the
    < news.answers archives at rtfm.mit.edu and ftp.uu.net; see
    < question 20.40.)
    ---
    > Archives associated with the comp.compilers newsgroup contain a
    > great deal of information about available compilers,
    > interpreters, grammars, etc. (for many languages). The
    > comp.compilers archives at http://compilers.iecc.com/ include an
    > FAQ list and a catalog of free compilers.


    ==========

    [Q18.7 Where can I get an ANSI-compatible lint?]

    < A: Products called PC-Lint and FlexeLint (in "shrouded source
    < form," for compilation on 'most any system) are available from
    <
    < Gimpel Software
    < 3207 Hogarth Lane
    < Collegeville, PA 19426 USA
    < (+1) 610 584 4261
    <
    ---
    > A: Products called PC-Lint and FlexeLint are available from Gimpel
    > Software at http://www.gimpel.com/.


    Another ANSI-compatible lint (which can also perform higher-
    < level formal verification) is LCLint, available via anonymous
    < ftp from larch.lcs.mit.edu in pub/Larch/lclint/.
    ---
    > level formal verification) is Splint (formerly lclint) at
    > http://lclint.cs.virginia.edu/.


    ==========

    [Q18.8 Don't ANSI function prototypes render lint obsolete?]

    < A: No.
    ---
    > A: Not really.


    ==========

    [Q18.9 Are there any C tutorials or other resources on the net?]

    < Tom Torfs has a nice tutorial at
    < http://members.xoom.com/tomtorfs/cintro.html .
    ---
    > Tom Torfs has a nice tutorial at http://cprog.tomsweb.net .


    "Notes for C programmers," by Christopher Sawtell, are
    < available from svr-ftp.eng.cam.ac.uk in misc/sawtell_C.shar and
    < garbo.uwasa.fi in /pc/c-lang/c-lesson.zip .
    ---
    > available by ftp from svr-ftp.eng.cam.ac.uk in
    > misc/sawtell_C.shar and garbo.uwasa.fi in pc/c-lang/c-
    > lesson.zip, or on the web at
    > http://www.fi.uib.no/Fysisk/Teori/KURS/OTHER/newzealand.html .


    The Coronado Enterprises C tutorials are available on Simtel
    < mirrors in pub/msdos/c or on the web at http://www.swcp.com/~dodrill .
    ---
    > mirrors in pub/msdos/c or on the web at
    > http://www.coronadoenterprises.com/tutorials/c/index.html .


    < Rick Rowe has a tutorial which is available from ftp.netcom.com
    < as pub/rowe/tutorde.zip or ftp.wustl.edu as
    < pub/MSDOS_UPLOADS/programming/c_language/ctutorde.zip .

    < There is evidently a web-based course at
    < http://www.strath.ac.uk/CC/Courses/CCourse/CCourse.html .
    ---
    > There is a web-based course by Steve Holmes at
    > http://www.strath.ac.uk/IT/Docs/Ccourse/ .


    ==========

    [Q18.10 What's a good book for learning C?]

    Several sets of annotations and errata are available on the net, see
    e.g. http://www.csd.uwo.ca/~jamie/.Refs/.Footnotes/C-annotes.html ,
    http://www.eskimo.com/~scs/cclass/cclass.html , and
    < http://www.lysator.liu.se/c/c-errata.html#main .
    ---
    > http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html .


    < Mitch Wright maintains an annotated bibliography of C and Unix
    < books; it is available for anonymous ftp from ftp.rahul.net in
    < directory pub/mitch/YABL/.

    < Scott McMahon has a nice set of reviews at
    < http://www.skwc.com/essent/cyberreviews.html .

    The Association of C and C++ Users (ACCU) maintains a
    < comprehensive set of bibliographic reviews of C/C++ titles, at
    < http://bach.cis.temple.edu/accu/bookcase or
    < http://www.accu.org/accu .
    <
    ---
    > comprehensive set of bibliographic reviews of C/C++ titles at
    > http://www.accu.org/bookreviews/public/.


    < This FAQ list's editor has a large collection of assorted
    < old recommendations which various people have posted; it
    < is available upon request.

    ==========

    [Q18.13 Where can I find the sources of the standard C libraries?]

    < A: One source (though not public domain) is _The Standard C
    < Library_, by P.J. Plauger (see the Bibliography).
    < Implementations of all or part of the C library have been
    < written and are readily available as part of the NetBSD and GNU
    < (also Linux) projects.
    ---
    > A: The GNU project has a complete implementation at
    > http://www.gnu.org/software/libc/. Another source (though not
    > public domain) is _The Standard C Library_, by P.J. Plauger (see
    > the Bibliography).


    ==========

    [Q18.15 Where can I get a BNF or YACC grammar for C?]

    A: The definitive grammar is of course the one in the ANSI
    < standard; see question 11.2. Another grammar (along with
    < one for C++) by Jim Roskind is in pub/c++grammar1.1.tar.Z
    < at ics.uci.edu (or perhaps ftp.ics.uci.edu, or perhaps
    < OLD/pub/c++grammar1.1.tar.Z), or at ftp.eskimo.com in
    < u/s/scs/roskind_grammar.Z .
    ---
    > standard; see question 11.2. Another grammar by Jim Roskind
    > is available at ftp.eskimo.com in u/s/scs/roskind_grammar.Z .


    < A fleshed-out, working instance of the ANSI grammar
    ---
    > A fleshed-out, working instance of the ANSI C90 grammar
    > (due to Jeff Lee) is on ftp.uu.net (see question 18.16) in
    > usenet/net.sources/ansi.c.grammar.Z (including a companion
    > lexer).


    ==========

    [Q18.15d I need code for performing multiple precision arithmetic.]

    A: Some popular packages are the "quad" functions within the BSD
    Unix libc sources (ftp.uu.net, /systems/unix/bsd-sources/.../
    < /src/lib/libc/quad/*), the GNU MP library, the MIRACL package
    < (see http://indigo.ie/~mscott/ ), and the old Unix libmp.a.
    ---
    > src/lib/libc/quad/*), the GNU MP library "libmp", the MIRACL
    > package (see http://indigo.ie/~mscott/ ), the "calc" program by
    > David Bell and Landon Curt Noll, and the old Unix libmp.a.


    ==========

    [Q19.1 How can I read a single character from the keyboard...]

    < Note that the answers are often not unique even across different
    < variants of a system; bear in mind when answering system-
    ---
    > Note that the answers may differ even across variants of
    > otherwise similar systems (e.g. across different variants of
    > Unix); bear in mind when answering system-specific questions

    that the answer that applies to your system may not apply to
    everyone else's.

    ==========

    [Q19.3 How can I display a percentage-done indication...]

    current line. The character '\b' is a backspace, and will
    < usually move the cursor one position to the left.
    ---
    > usually move the cursor one position to the left. (But remember
    > to call fflush(), too.)


    ==========

    [Q19.8 How can I direct output to the printer?]

    > Under some circumstances, another (and perhaps the only)
    > possibility is to use a window manager's screen-capture
    > function, and print the resulting bitmap.


    ==========

    [Q19.10 How can I do graphics?]

    > A modern, platform-independent graphics library (which also
    > supports 3D graphics and animation) is OpenGL. Other graphics
    > standards which may be of interest are GKS and PHIGS.


    ==========

    [Q19.12 How can I find out the size of a file, prior to reading it in?]

    You can fseek() to the end and then use
    ftell(), or maybe try fstat(), but these tend to have the same
    sorts of problems: fstat() is not portable, and generally tells
    you the same thing stat() tells you; ftell() is not guaranteed
    < to return a byte count except for binary files. Some systems
    ---
    > to return a byte count except for binary files (but, strictly
    > speaking, binary files don't necessarily support fseek to
    > SEEK_END at all). Some systems provide functions called

    filesize() or filelength(), but these are obviously not
    portable, either.

    ==========

    [Q19.20 How can I read a directory in a C program?]

    (MS-DOS also has FINDFIRST and FINDNEXT routines which
    < do essentially the same thing.)
    ---
    > do essentially the same thing, and MS Windows has FindFirstFile
    > and FindNextFile.)


    ==========

    [Q19.23 How can I allocate arrays or structures bigger than 64K?]

    to allocate huge amounts of it contiguously. (The C Standard
    does not guarantee that single objects can be 32K or larger,
    < or 64K for C9X.) Often it's a good idea to use data
    ---
    > or 64K for C99.) Often it's a good idea to use data


    ==========

    [Q19.25 How can I access memory (a memory-mapped device...]

    < Then, *magicloc refers to the location you want.
    ---
    > Then, *magicloc refers to the location you want. If the
    > location is a memory-mapped I/O register, you will probably also
    > want to use the volatile qualifier.


    ==========

    [Q19.27 How can I invoke another program...]

    > Depending on your operating system, you may also be able to use
    > system calls such as exec or spawn (or execl, execv, spawnl,
    > spawnv, etc.).


    ==========

    [Q19.37 How can I implement a delay... with sub-second resolution?]

    < A: Unfortunately, there is no portable way. V7 Unix, and derived
    < systems, provided a fairly useful ftime() function with
    < resolution up to a millisecond, but it has disappeared from
    < System V and POSIX. Other routines you might look for on your
    ---
    > A: Unfortunately, there is no portable way. Routines you might
    > look for on your system include clock(), delay(), ftime(),
    > gettimeofday(), msleep(), nap(), napms(), nanosleep(),
    > setitimer(), sleep(), Sleep(), times(), and usleep().


    ==========

    [Q19.40 How do I... Use sockets? Do networking?]

    and W. R. Stevens's _UNIX Network Programming_. There is also
    plenty of information out on the net itself, including the
    < "Unix Socket FAQ" at http://kipper.york.ac.uk/~vic/sock-faq/
    ---
    > "Unix Socket FAQ" at http://www.developerweb.net/sock-faq/


    > and "Beej's Guide to Network Programming" at
    > http://www.ecst.csuchico.edu/~beej/guide/net/.


    > (One tip: depending on your OS, you may need to explicitly
    > request the -lsocket and -lnsl libraries; see question 13.25.)


    ==========

    [Q20.14 Are pointers really faster than arrays?]

    < It is "usually" faster to march through large arrays with
    ---
    > For conventional machines, it is usually faster to march through
    > large arrays with pointers rather than array subscripts, but for
    > some processors the reverse is true.


    ==========

    [Q20.20 Why don't C comments nest? ...]

    < Note also that // comments, as in C++, are not yet legal in C,
    < so it's not a good idea to use them in C programs (even if your
    < compiler supports them as an extension).
    ---
    > Note also that // comments have only become legal in C as of
    > C99.


    ==========

    < 20.20b: Is C a great language, or what? Where else could you write
    ---
    > 20.21b: Is C a great language, or what? Where else could you write

    something like a+++++b ?

    ==========

    [Q20.27 ... Can I use a C++ compiler to compile C code?]

    < compilation modes. See also questions 8.9 and 20.20.
    ---
    > compilation modes. (But it's usually a bad idea to compile
    > straight C code as if it were C++; the languages are different
    > enough that you'll generally get poor results.) See also
    > questions 8.9 and 20.20.


    ==========

    < 20.32: Will 2000 be a leap year? Is (year % 4 == 0) an accurate test
    < for leap years?
    ---
    > 20.32: Is (year % 4 == 0) an accurate test for leap years? (Was 2000 a
    > leap year?)


    < A: Yes and no, respectively. The full expression for the present
    < Gregorian calendar is
    ---
    > A: No, it's not accurate (and yes, 2000 was a leap year).
    > The full expression for the present Gregorian calendar is


    ==========

    [Q20.34 ...how do you write a program which produces its own source code...?]

    < (This program, like many of the genre, neglects to #include
    < <stdio.h>, and assumes that the double-quote character " has the
    ---
    > (This program has a few deficiencies, among other things
    > neglecting to #include <stdio.h>, and assuming that the double-

    quote character " has the value 34, as it does in ASCII.)

    > Here is an improved version, posted by James Hu:
    >
    > #define q(k)main(){return!puts(#k"\nq("#k")");}
    > q(#define q(k)main(){return!puts(#k"\nq("#k")");})


    ==========

    [Q20.35 What is "Duff's Device"?]

    < A: It's a devastatingly deviously unrolled byte-copying loop,
    < devised by Tom Duff while he was at Lucasfilm. In its "classic"
    < form, it looks like:
    ---
    > A: It's a devastatingly devious way of unrolling a loop, devised by
    > Tom Duff while he was at Lucasfilm. In its "classic" form, it
    > was used to copy bytes, and looked like this:


    ==========

    [Q20.38 Where does the name "C" come from, anyway?]

    A: C was derived from Ken Thompson's experimental language B, which
    was inspired by Martin Richards's BCPL (Basic Combined
    Programming Language), which was a simplification of CPL
    < (Cambridge Programming Language).
    ---
    > (Combined Programming Language, or perhaps Cambridge Programming
    > Language).


    ==========

    [Q20.40 Where can I get extra copies of this list?]

    < What about back issues?

    < This list is an evolving document containing questions which
    < have been Frequent since before the Great Renaming; it is not
    < just a collection of this month's interesting questions. Older
    < copies are obsolete and don't contain much, except the
    < occasional typo, that the current list doesn't.

    ==========

    [Bibliography]

    Samuel P. Harbison and Guy L. Steele, Jr., _C: A Reference Manual_,
    < Fourth Edition, Prentice-Hall, 1995, ISBN 0-13-326224-3. [H&S]
    ---
    > Fourth Edition, Prentice-Hall, 1995, ISBN 0-13-326224-3. [There is
    > also a fifth edition: 2002, ISBN 0-13-089592-X.] [H&S]


    Donald E. Knuth, _The Art of Computer Programming_. Volume 1:
    < _Fundamental Algorithms_, Second Edition, Addison-Wesley, 1973, ISBN
    < 0-201-03809-9. Volume 2: _Seminumerical Algorithms_, Second Edition,
    < Addison-Wesley, 1981, ISBN 0-201-03822-6. Volume 3: _Sorting and
    < Searching_, Addison-Wesley, 1973, ISBN 0-201-03803-X. (New editions
    < are coming out!) [Knuth]
    ---
    > _Fundamental Algorithms_, Third Edition, Addison-Wesley, 1997, ISBN
    > 0-201-89683-4. Volume 2: _Seminumerical Algorithms_, Third Edition,
    > 1997, ISBN 0-201-89684-2. Volume 3: _Sorting and Searching_, Second
    > Edition, 1998, ISBN 0-201-89685-0. [Knuth]


    Robert Sedgewick, _Algorithms in C_, Addison-Wesley, 1990,
    < ISBN 0-201-51425-7. (A new edition is being prepared;
    < the first half is ISBN 0-201-31452-5.)
    ---
    > ISBN 0-201-51425-7. (A new edition is being prepared; the first two
    > volumes are ISBN 0-201-31452-5 and 0-201-31663-3.)


    > Peter van der Linden, _Expert C Programming: Deep C Secrets_, Prentice
    > Hall, 1994, ISBN 0-13-177429-8.


    ==========

    [Acknowledgements]

    > Thanks to Jamshid Afshar, Lauri Alanko, Michael B. Allen, David
    > Anderson, Jens Andreasen, Tanner Andrews, Sudheer Apte, Joseph
    > Arceneaux, Randall Atkinson, Kaleb Axon, Daniel Barker, Rick Beem, Peter
    > Bennett, Mathias Bergqvist, Wayne Berke, Dan Bernstein, Tanmoy
    > Bhattacharya, John Bickers, Kevin Black, Gary Blaine, Yuan Bo, Mark J.
    > Bobak, Anthony Borla, Dave Boutcher, Alan Bowler, ,

    Michael Bresnahan, Walter Briscoe, Vincent Broman, Robert T. Brown, Stan
    Brown, John R. Buchan, Joe Buehler, Kimberley Burchett, Gordon Burditt,
    > Scott Burkett, Eberhard Burr, Burkhard Burow, Conor P. Cahill, D'Arcy

    J.M. Cain, Christopher Calabrese, Ian Cargill, Vinit Carpenter, Paul
    Carter, Mike Chambers, Billy Chambless, C. Ron Charlton, Franklin Chen,
    Jonathan Chen, Raymond Chen, Richard Cheung, Avinash Chopde, Steve
    Clamage, Ken Corbin, Dann Corbit, Ian Cottam, Russ Cox, Jonathan
    > Coxhead, Lee Crawford, Nick Cropper, Steve Dahmer, Jim Dalsimer, Andrew
    > Daviel, James Davies, John E. Davis, Ken Delong, Norm Diamond, Jamie
    > Dickson, Bob Dinse, dlynes@plenary-software, Colin Dooley, Jeff Dunlop,
    > Ray Dunn, Stephen M. Dunn, Andrew Dunstan, Michael J. Eager, Scott

    Ehrlich, Arno Eigenwillig, Yoav Eilat, Dave Eisen, Joe English, Bjorn
    > Engsig, David Evans, Andreas Fassl, Clive D.W. Feather, Dominic Feeley,
    > Simao Ferraz, Pete Filandr, Bill Finke Jr., Chris Flatters, Rod Flores,

    Alexander Forst, Steve Fosdick, Jeff Francis, Ken Fuchs, Tom Gambill,
    > Dave Gillespie, Samuel Goldstein, Willis Gooch, Tim Goodwin, Alasdair
    > Grant, W. Wesley Groleau, Ron Guilmette, Craig Gullixson, Doug Gwyn,
    > Michael Hafner, Zhonglin Han, Darrel Hankerson, Tony Hansen, Douglas

    Wilhelm Harder, Elliotte Rusty Harold, Joe Harrington, Guy Harris, John
    > Hascall, Adrian Havill, Richard Heathfield, Des Herriott, Ger Hobbelt,
    > Sam Hobbs, Joel Ray Holveck, Jos Horsmeier, Syed Zaeem Hosain, Blair
    > Houghton, Phil Howard, Peter Hryczanek, James C. Hu, Chin Huang, Jason
    > Hughes, David Hurt, Einar Indridason, Vladimir Ivanovic, Jon Jagger,
    > Ke Jin, Kirk Johnson, David Jones, Larry Jones, Morris M. Keesan, Arjan
    > Kenter, Bhaktha Keshavachar, James Kew, Bill Kilgore, Darrell Kindred,

    Lawrence Kirby, Kin-ichi Kitano, Peter Klausler, John Kleinjans, Andrew
    > Koenig, Thomas Koenig, Adam Kolawa, Jukka Korpela, Przemyslaw Kowalczyk,
    > Ajoy Krishnan T, Anders Kristensen, Jon Krom, Markus Kuhn, Deepak
    > Kulkarni, Yohan Kun, B. Kurtz, Kaz Kylheku, Oliver Laumann, John Lauro,
    > Felix Lee, Mike Lee, Timothy J. Lee, Tony Lee, Marty Leisner, Eric
    > Lemings, Dave Lewis, Don Libes, Brian Liedtke, Philip Lijnzaad, James
    > D. Lin, Keith Lindsay, Yen-Wei Liu, Paul Long, Patrick J. LoPresti,
    > Christopher Lott, Tim Love, Paul Lutus, Mike McCarty, Tim McDaniel,
    > Michael MacFaden, Allen Mcintosh, J. Scott McKellar, Kevin McMahon,

    Stuart MacMartin, John R. MacMillan, Robert S. Maier, Andrew Main,
    Bob Makowski, Evan Manning, Barry Margolin, George Marsaglia, George
    Matas, Brad Mears, Wayne Mery, De Mickey, Rich Miller, Roger Miller,
    Bill Mitchell, Mark Moraes, Darren Morby, Bernhard Muenzer, David Murphy,
    Walter Murray, Ralf Muschall, Ken Nakata, Todd Nathan, Taed Nelson,
    > Pedro Zorzenon Neto, Daniel Nielsen, Landon Curt Noll, Tim Norman, Paul

    Nulsen, David O'Brien, Richard A. O'Keefe, Adam Kolawa, Keith Edward
    > O'hara, James Ojaste, Max Okumoto, Hans Olsson, Thomas Otahal, Lloyd
    > Parkes, Bob Peck, Harry Pehkonen, Andrew Phillips, Christopher Phillips,

    Francois Pinard, Nick Pitfield, Wayne Pollock, , Dan Pop,
    > Don Porges, Claudio Potenza, Lutz Prechelt, Lynn Pye, Ed Price, Kevin
    > D. Quitt, Pat Rankin, Arjun Ray, Eric S. Raymond, Christoph Regli,
    > Peter W. Richards, James Robinson, Greg Roelofs, Eric Roode, Manfred
    > Rosenboom, J.M. Rosenstock, Rick Rowe, Michael Rubenstein, Erkki
    > Ruohtula, John C. Rush, John Rushford, Kadda Sahnine, Tomohiko Sakamoto,

    Matthew Saltzman, Rich Salz, Chip Salzenberg, Matthew Sams, Paul Sand,
    DaviD W. Sanderson, Frank Sandy, Christopher Sawtell, Jonas Schlein,
    Paul Schlyter, Doug Schmidt, Rene Schmit, Russell Schulz, Dean Schulze,
    > Jens Schweikhardt, Chris Sears, Peter Seebach, Gisbert W. Selke,
    > Patricia Shanahan, Girija Shanker, Clinton Sheppard, Aaron Sherman,
    > Raymond Shwake, Nathan Sidwell, Thomas Siegel, Peter da Silva, Andrew
    > Simmons, Joshua Simons, Ross Smith, Thad Smith, Henri Socha, Leslie
    > J. Somos, Eric Sosman, Henry Spencer, David Spuler, Frederic Stark,

    James Stern, Zalman Stern, Michael Sternberg, Geoff Stevens, Alan
    > Stokes, Bob Stout, Dan Stubbs, Tristan Styles, Richard Sullivan, Steve
    > Sullivan, Melanie Summit, Erik Talvola, Christopher Taylor, Dave Taylor,
    > Clarke Thatcher, Wayne Throop, Chris Torek, Steve Traugott, Brian Trial,

    Nikos Triantafillis, Ilya Tsindlekht, Andrew Tucker, Goran Uddeborg,
    > Rodrigo Vanegas, Jim Van Zandt, Momchil Velikov, Wietse Venema, Tom

    Verhoeff, Ed Vielmetti, Larry Virden, Chris Volpe, Mark Warren, Alan
    Watson, Kurt Watzka, Larry Weiss, Martin Weitzel, Howard West, Tom
    > White, Freek Wiedijk, Stephan Wilms, Tim Wilson, Dik T. Winter, Lars
    > Wirzenius, Dave Wolverton, Mitch Wright, Conway Yee, James Youngman,

    Ozan S. Yigit, and Zhuo Zang, who have contributed, directly or
    indirectly, to this article.

    ====================


    Next, here are all sorts of minor wording changes and cosmetic
    differences:

    ==========
    < [Last modified February 7, 1999 by scs.]
    ---
    > [Last modified July 3, 2004 by scs.]

    ==========
    Certain topics come up again and again on this newsgroup. They are good
    questions, and the answers may not be immediately obvious, but each time
    they recur, much net bandwidth and reader time is wasted on repetitive
    < responses, and on tedious corrections to the incorrect answers which are
    < inevitably posted.
    ---
    > responses, and on tedious corrections to any incorrect answers which may
    > unfortunately be posted.

    ==========
    If you have a question about C which is not answered in this article,
    < first try to answer it by checking a few of the referenced books, or by
    < asking knowledgeable colleagues, before posing your question to the net
    ---
    > books, or one of the expanded versions mentioned below, before posing

    your question to the net at large.
    ==========
    (However, this is a large and heavy document, so don't
    < assume that everyone on the newsgroup has managed to read all of it in
    ---
    > assume that everyone on the net has managed to read all of it in detail,

    and please don't roll it up and thwack people over the head with it just
    because they missed their answer in it.)
    ==========
    < be able to obtain the most up-to-date copy on the web at
    ---
    > be able to obtain the most up-to-date copy at

    http://www.eskimo.com/~scs/C-faq/top.html or http://www.faqs.org/faqs/ ,
    ==========
    < or from one of the ftp sites mentioned in question 20.40.
    ---
    > or via ftp from ftp://rtfm.mit.edu/. (See also question 20.40.)

    ==========
    Since this list is modified from time to time, its question numbers
    may not match those in older or newer copies which are in circulation;
    < be careful when referring to FAQ list entries by number alone.
    ---
    > so be careful when referring to FAQ list entries by number alone.

    ==========
    < Other versions of this document are also available. Posted along
    ---
    > Several other versions of this document are available. Posted along

    with it are an abridged version and (when there are changes) a list of
    ==========
    < is available on the web at the aforementioned URL. Finally, for those
    < who might prefer a bound, hardcopy version (and even longer answers to
    < even more questions!), a book-length version has been published by
    < Addison-Wesley (ISBN 0-201-84519-9).
    ---
    > is available on the web at the aforementioned URL. For those who might
    > prefer a bound, hardcopy version, a book-length version has been
    > published by Addison-Wesley (ISBN 0-201-84519-9). The hypertext and
    > book versions include additional questions and more detailed answers, so
    > you might want to check one of them if you still have questions after
    > reading this posted list.

    ==========
    < This article is always being improved. Your input is welcomed. Send
    ---
    > This article can always be improved. Your input is welcome. Send

    your comments to .
    ==========
    < 1.1: How do you decide which integer type to use?
    ---
    > 1.1: How should I decide which integer type to use?

    ==========
    < float and double. None of the above rules apply if the address
    < of a variable is taken and must have a particular type.
    ---
    > float and double. None of the above rules apply if pointers to
    > the variable must have a particular type.

    ==========
    < 1.4: What should the 64-bit type on a machine that can support it?
    ---
    > 1.4: What should the 64-bit type be on a machine that can support it?

    ==========
    The .c file containing the definition should also #include the
    < same header file, so that the compiler can check that the definition
    ---
    > same header file, so the compiler can check that the definition

    matches the declarations.
    ==========
    clear. The problem with the NODEPTR example is that the typedef
    < has not been defined at the point where the "next" field is
    ---
    > has not yet been defined at the point where the "next" field is

    declared.
    ==========
    < 1.21: How do I declare an array of N pointers to functions returning
    < pointers to functions returning pointers to characters?
    ---
    > 1.21: How do I construct and understand declarations of complicated
    > types such as "array of N pointers to functions returning
    > pointers to functions returning pointers to char"?

    ==========
    < A: The first part of this question can be answered in at least
    < three ways:
    ---
    > A: There are at least three ways of answering this question:

    ==========
    cdecl can also explain complicated declarations, help with
    < casts, and indicate which set of parentheses the arguments
    ---
    > casts, and indicate which set of parentheses the parameters

    go in
    ==========
    < Any good book on C should explain how to read these complicated C
    ---
    > A good book on C should explain how to read these complicated

    declarations "inside out" to understand them ("declaration
    mimics use").
    ==========
    1.30: What am I allowed to assume about the initial values
    < of variables which are not explicitly initialized?
    ---
    > of variables and arrays which are not explicitly initialized?

    ==========
    A: Uninitialized variables with "static" duration (that is, those
    declared outside of functions, and those declared with the
    < storage class static), are guaranteed to start out as zero,
    ---
    > storage class static), are guaranteed to start out as zero, just

    as if the programmer had typed "= 0".
    ==========
    A: Is the declaration of a static or non-local variable? Function
    < calls are allowed only in initializers for automatic variables
    ---
    > calls are allowed in initializers only for automatic variables

    ==========
    A: A string literal can be used in two slightly different ways. As
    < an array initializer (as in the declaration of char a[]), it
    ---
    > an array initializer (as in the declaration of char a[] in the
    > question), it specifies the initial values of the characters in

    that array.
    ==========
    Anywhere else, it turns into an unnamed, static array of
    characters, which may be stored in read-only memory,
    < which is why you can't safely modify it.
    ---
    > and which therefore cannot necessarily be modified.

    ==========
    (For compiling old code, some compilers have a switch
    < controlling whether strings are writable or not.)
    ---
    > controlling whether string literals are writable or not.)

    ==========
    < When the name of a function appears in an expression like this,
    ---
    > When the name of a function appears in an expression,

    it "decays" into a pointer (that is, it has its address
    implicitly taken), much as an array name does.
    ==========
    < 2.4: What's the best way of implementing opaque (abstract) data types
    < in C?
    ---
    > 2.4: How can I implement opaque (abstract) data types in C?

    ==========
    < A: No. There is no single, good way for a compiler to implement
    < implicit structure comparison (i.e. to support the == operator
    ---
    > A: No. There is not a good way for a compiler to implement
    > structure comparison (i.e. to support the == operator

    for structures) which is consistent with C's low-level flavor.
    ==========
    A simple byte-by-byte comparison could founder on random bits
    < present in unused "holes" in the structure (such padding is used
    < to keep the alignment of later fields correct; see question 2.12).
    ---
    > present in unused "holes" in the structure (see question 2.12).

    ==========
    < Note also that if the structure contains any pointers, only
    ---
    > Also, if the structure contains any pointers, only

    the pointer values will be written, and they are most unlikely
    to be valid when read back in.
    ==========
    Finally, note that for widespread portability you must use the
    < "b" flag when fopening the files; see question 12.38.
    ---
    > "b" flag when opening the files; see question 12.38.

    ==========
    < A: Structures may have this padding (as well as internal padding),
    < if necessary, to ensure that alignment properties will be
    < preserved when an array of contiguous structures is allocated.
    < Even when the structure is not part of an array, the end padding
    ---
    > A: Padding at the end of a structure may be necessary to preserve
    > alignment when an array of contiguous structures is allocated.
    > Even when the structure is not part of an array, the padding

    remains, so that sizeof can always return a consistent size.
    ==========
    < A: At the present time, there is little difference. The C Standard
    ---
    > A: There is little difference. The C Standard

    says that enumerations may be freely intermixed with other
    integral types, without errors.
    ==========
    that they obey block scope. (A compiler may also generate
    < nonfatal warnings when enumerations and integers are
    < indiscriminately mixed, since doing so can still be considered
    < bad style even though it is not strictly illegal.)
    ---
    > nonfatal warnings when enumerations are indiscriminately mixed,
    > since doing so can still be considered bad style.)

    ==========
    (Loosely speaking, by "multiple, ambiguous side effects" we mean
    < any combination of ++, --, =, +=, -=, etc. in a single expression
    ---
    > any combination of increment, decrement, and assignment operators

    in a single expression which causes the same object either to be
    modified twice or modified and then inspected.
    ==========
    < Note that (long int)(a * b) would *not* have the desired effect.
    ---
    > Notice that (long int)(a * b) would *not* have the desired
    > effect.

    ==========
    < or a delibrate but nonstandard extension if a particular
    ---
    > or a deliberate but nonstandard extension if a particular

    ==========
    < Whenever possible, you should choose appropriate pointer types
    < in the first place, instead of trying to treat one type
    ---
    > When possible, however, you should choose appropriate pointer
    > types in the first place, rather than trying to treat one type

    as another.
    ==========
    < void * acts as a generic pointer only because conversions are
    ---
    > void * acts as a generic pointer only because conversions (if
    > necessary) are applied automatically when other pointer types

    are assigned to and from void *'s;
    ==========
    < 4.12: I've seen different methods used for calling functions via
    ---
    > 4.12: I've seen different syntax used for calling functions via

    pointers. What's the story?
    ==========
    pointers, and that "real" function names always decay implicitly
    into pointers (in expressions, as they do in initializations;
    < see question 1.34). This reasoning (which is in fact used in
    < the ANSI standard) means that
    ---
    > see question 1.34). This reasoning means that

    ==========
    function pointer followed by an argument list except call the
    < function pointed to.) An explicit * is still allowed.
    ---
    > function pointed to.)

    ==========
    > The ANSI C Standard essentially adopts the latter
    > interpretation, meaning that the explicit * is not required,
    > though it is still allowed.

    ==========
    < 5.4: What is NULL and how is it #defined?
    ---
    > 5.4: What is NULL and how is it defined?

    ==========
    < preprocessor macro NULL is #defined (by <stdio.h> and several
    < other headers) with the value 0, possibly cast to (void *)
    ---
    > preprocessor macro NULL is defined (by <stdio.h> and several
    > other headers) as a null pointer constant, typically 0 or
    > ((void *)0)

    ==========
    < NULL should *only* be used for pointers; see question 5.9.
    ---
    > NULL should be used *only* as a pointer constant; see question 5.9.

    ==========
    < A: Not in general. The complication is that there are machines
    ---
    > A: Not in the most general case. The complication is that there

    are machines which use different internal representations for
    pointers to different types of data.
    ==========
    < pointer arguments of other types would still be problematical,
    ---
    > pointer arguments of other types could still (in the absence
    > of prototypes) be problematical,

    ==========
    This article uses the phrase "null pointer" (in lower case) for
    < sense 1, the character "0" or the phrase "null pointer constant"
    ---
    > sense 1, the token "0" or the phrase "null pointer constant"

    for sense 3, and the capitalized word "NULL" for sense 4.
    ==========
    < A: C programmers traditionally like to know more than they might
    < need to about the underlying machine implementation.
    ---
    > A: C programmers traditionally like to know a lot (perhaps more
    > than they need to) about the underlying machine implementation.

    ==========
    integer zero instead of an error message, and if that uncast 0
    < was supposed to be a null pointer constant, the code may not
    < work.
    ---
    > was supposed to be a null pointer constant, the resulting
    > program may not work.

    ==========
    Some 64-bit Cray machines represent int * in the lower 48 bits
    < of a word; char * additionally uses the upper 16 bits to
    ---
    > of a word; char * additionally uses some of the upper 16 bits to

    indicate a byte address within a word.
    ==========
    A: This message, which typically occurs with MS-DOS compilers, means
    < that you've written, via a null (perhaps because uninitialized)
    < pointer, to an invalid location (probably offset 0 in the
    < default data segment).
    ---
    > means that you've written, via a null pointer, to an invalid
    > location -- probably offset 0 in the default data segment.

    ==========
    < A: In one source file you defind an array of characters and in the
    ---
    > A: In one source file you defined an array of characters and in the

    ==========
    < It is important to realize that a reference like x[3] generates
    ---
    > It is useful to realize that a reference like x[3] generates

    different code depending on whether x is an array or a pointer.
    ==========
    < If you can't use C9X or gcc, you'll have to use malloc(), and
    ---
    > If you can't use C99 or gcc, you'll have to use malloc(), and

    remember to call free() before the function returns.
    ==========
    < Finally, in C9X you can use a variable-length array.
    ---
    > Finally, in C99 you can use a variable-length array.

    ==========
    A: The rule (see question 6.3) by which arrays decay into pointers
    < is not applied recursively.
    ---
    > is *not* applied recursively.

    ==========
    not provide an automatically-managed string type. C compilers
    < only allocate memory for objects explicitly mentioned in the
    ---
    > allocate memory only for objects explicitly mentioned in the

    source code (in the case of strings, this includes character
    ==========
    < A: You got lucky, I guess. The memory pointed to by the
    < unitialized pointer p happened to be writable by you,
    ---
    > A: You got lucky, I guess. The memory randomly pointed to by
    > the uninitialized pointer p happened to be writable by you,

    ==========
    A pointer value which has been freed is, strictly speaking,
    < invalid, and *any* use of it, even if is not dereferenced,
    ---
    > invalid, and *any* use of it, even if it is not dereferenced,

    can theoretically lead to trouble,
    ==========
    A: In C, characters are represented by small integers corresponding
    < to their values (in the machine's character set), so you
    ---
    > to their values in the machine's character set. Therefore, you

    don't need a conversion function: if you have the character, you
    have its value.
    ==========
    < DEBUG("i = %d" _ i)
    ---
    > DEBUG("i = %d" _ i);

    ==========
    controversial trigraph sequences). The ANSI C standard also
    < formalizes the C run-time library support routines.
    ---
    > formalized the C run-time library support routines.

    ==========
    < The text of the Rationale (not the full Standard) can be
    < obtained by anonymous ftp from ftp.uu.net (see question 18.16)
    < in directory doc/standards/ansi/X3.159-1989, and is also
    < available on the web at http://www.lysator.liu.se/c/rat/title.html .
    < The Rationale has also been printed by Silicon Press,
    < ISBN 0-929306-07-4.
    ---
    > The text of the original ANSI Rationale can be obtained by
    > anonymous ftp from ftp.uu.net (see question 18.16) in directory
    > doc/standards/ansi/X3.159-1989, and is also available on the web
    > at http://www.lysator.liu.se/c/rat/title.html . That Rationale
    > has also been printed by Silicon Press, ISBN 0-929306-07-4.

    ==========
    < Public review drafts of C9X are available from ISO/IEC
    ---
    > Public review drafts of C9X were available from ISO/IEC

    ==========
    11.5: Why does the declaration
    extern int f(struct x *p);
    < give me an obscure warning message about "struct x introduced in
    < prototype scope"?
    ---
    > give me an obscure warning message about "struct x declared
    > inside parameter list"?

    ==========
    A: "const char *p" (which can also be written "char const *p")
    declares a pointer to a constant character (you can't change
    < the character); "char * const p" declares a constant pointer
    ---
    > any pointed-to characters); "char * const p" declares a constant

    pointer to a (variable) character (i.e. you can't change the
    pointer).
    ==========
    < A: The problem is older linkers which are under the control of
    ---
    > A: The problem is linkers which are under control of

    neither the ANSI/ISO Standard nor the C compiler developers
    on the systems which have them.
    ==========
    If you're interested in writing portable code, you can ignore
    < the distinctions, as you'll want to avoid code that depends
    ---
    > the distinctions, as you'll usually want to avoid code that

    depends on any of the three behaviors.
    ==========
    A: The functions in <locale.h> begin to provide some support for
    < these operations, but there is no standard routine for doing
    ---
    > these operations, but there is no standard function for doing

    either task.
    ==========
    < If you're worried about using floating point, you could use
    ---
    > If you'd rather not use floating point, another method is

    rand() / (RAND_MAX / N + 1)
    ==========
    < A: In general, a header file contains only declarations.
    ---
    > A: In general, a header file contains only external declarations.

    ==========
    how carefully your compiler's binary/decimal conversion routines
    (such as those used by printf) have been written, you may see
    < discrepancies when numbers (especially low-precision floats) not
    < exactly representable in base 2 are assigned or read in and then
    ---
    > discrepancies when numbers not exactly representable in base 2

    are assigned or read in and then printed (i.e. converted from
    base 10 to base 2 and back again).
    ==========
    < Another possibility is to to format the value in question using
    ---
    > Another possibility is to format the value in question using

    sprintf(): on many systems it generates strings like "NaN"
    ==========
    < A: Some compilers for small machines, including Borland's
    ---
    > A: Some compilers for small machines, including Turbo C

    Ritchie's original PDP-11 compiler), leave out certain floating
    ==========
    < char *vstrcat(char *first, ...)
    ---
    > char *vstrcat(const char *first, ...)

    ==========
    < void error(char *fmt, ...)
    ---
    > void error(const char *fmt, ...)

    ==========
    < examples in questions 5.2 and 15.4). Finally, if their types
    ---
    > examples in questions 5.2 and 15.4). Finally, if the types
    > are predictable, you can pass an explicit count of the number of

    ==========
    < local arrays. Many systems have fixed-size stacks, and
    ---
    > local arrays. Many systems have fixed-size stacks, and even

    those which perform dynamic stack allocation automatically
    (e.g. Unix) can be confused when the stack tries to grow by a
    huge chunk all at once.
    ==========
    < 16.8: What do "Segmentation violation" and "Bus error" mean?
    ---
    > 16.8: What do "Segmentation violation", "Bus error", and "General
    > protection fault" mean?

    ==========
    < Finally, the author of this FAQ list teaches a C class
    < and has placed its notes on the web; they are at
    ---
    > Finally, the author of this FAQ list once taught a couple of
    > C classes and has placed their notes on the web; they are at

    ==========
    < 18.10: What's a good book for learning C?
    ---
    > 18.10: What's a good book for learning C? What about advanced books
    > and references?

    ==========
    < The GNU libplot package maintains the same spirit and supports
    < many modern plot devices;
    < see http://www.gnu.org/software/plotutils/plotutils.html .
    ---
    > The GNU libplot library, written by Robert Maier, maintains
    > the same spirit and supports many modern plot devices; see
    > http://www.gnu.org/software/plotutils/plotutils.html .

    ==========
    A: If the "size of a file" is the number of characters you'll be
    < able to read from it in C, it is difficult or impossible to
    ---
    > able to read from it in C, it can be difficult or impossible to

    determine this number exactly.
    ==========
    < readdir() only returns file names; if you need more
    ---
    > readdir() returns just the file names; if you need more

    information about the file, try calling stat().
    ==========
    < (Also, remember to call pclose().)
    ---
    > (Also, remember to call pclose() when you're done.)

    ==========
    busy-wait, but this is only an option on a single-user, single-
    < tasking machine as it is terribly antisocial to any other
    ---
    > tasking machine, as it is terribly antisocial to any other

    processes. Under a multitasking operating system, be sure to
    ==========
    It is possible, and desirable, for *most* of a program to be
    ANSI-compatible, deferring the system-dependent functionality to
    < a few routines in a few files which are rewritten for each
    < system ported to.
    ---
    > a few routines in a few files which are either heavily #ifdeffed
    > or rewritten entirely for each system ported to.

    ==========
    or have the function return a structure containing the
    < desired values, or (in a pinch) consider global variables.
    ---
    > desired values, or (in a pinch) you could theoretically use

    global variables.
    ==========
    is not only clearer to the human reader, it is more likely to be
    recognized by the compiler and turned into the most-efficient
    < code (e.g. using a swap instruction, if available).
    ---
    > code (e.g. perhaps even using an EXCH instruction).

    ==========
    < More information may be found in FORT.gz by Glenn Geers, available
    < via anonymous ftp from suphys.physics.su.oz.au in the src
    < directory.
    <
    < cfortran.h, a C header file, simplifies C/FORTRAN interfacing on
    < many popular machines. It is available via anonymous ftp from
    < zebra.desy.de or at http://www-zeus.desy.de/~burow .
    ---
    > For FORTRAN, more information may be found in FORT.gz by Glenn
    > Geers, available via anonymous ftp from suphys.physics.su.oz.au
    > in the src directory. Burkhard Burow's header file cfortran.h
    > simplifies C/FORTRAN interfacing on many popular machines.
    > It is available via anonymous ftp from zebra.desy.de or at
    > http://www-zeus.desy.de/~burow .

    ==========
    This FAQ list's maintainer also has available a list of a few
    < other commercial translation products, and some for more obscure
    < languages.
    ---
    > other translators.

    ==========
    < A: The contest is in a state of flux; see
    ---
    > A: The contest schedule varies over time; see

    ====================


    Finally, here are a few questions which don't really need to be in
    the posted-to-Usenet list every month. (As mentioned, though, they'll
    live on in the web-based version.)

    ==========

    < 1.22: How can I declare a function that can return a pointer to a
    < function of the same type? I'm building a state machine with
    < one function for each state, each of which returns a pointer to
    < the function for the next state. But I can't find a way to
    < declare the functions.
    <
    < A: You can't quite do it directly. Either have the function return
    < a generic function pointer, with some judicious casts to adjust
    < the types as the pointers are passed around; or have it return a
    < structure containing only a pointer to a function returning that
    < structure.

    ==========

    < 2.7: I heard that structures could be assigned to variables and
    < passed to and from functions, but K&R1 says not.
    <
    < A: What K&R1 said (though this was quite some time ago by now) was
    < that the restrictions on structure operations would be lifted
    < in a forthcoming version of the compiler, and in fact structure
    < assignment and passing were fully functional in Ritchie's
    < compiler even as K&R1 was being published. A few ancient C
    < compilers may have lacked these operations, but all modern
    < compilers support them, and they are part of the ANSI C
    < standard, so there should be no reluctance to use them.
    <
    < (Note that when a structure is assigned, passed, or returned,
    < the copying is done monolithically; the data pointed to by any
    < pointer fields is *not* copied.)

    ==========

    < 13.14b: Does C have any Year 2000 problems?
    <
    < A: No, although poorly-written C programs do.
    <
    < The tm_year field of struct tm holds the value of the year minus
    < 1900; this field will therefore contain the value 100 for the
    < year 2000. Code that uses tm_year correctly (by adding or
    < subtracting 1900 when converting to or from human-readable
    < 4-digit year representations) will have no problems at the turn
    < of the millennium. Any code that uses tm_year incorrectly,
    < however, such as by using it directly as a human-readable
    < 2-digit year, or setting it from a 4-digit year with code like
    <
    < tm.tm_year = yyyy % 100; /* WRONG */
    <
    < or printing it as an allegedly human-readable 4-digit year with
    < code like
    <
    < printf("19%d", tm.tm_year); /* WRONG */
    <
    < will have grave y2k problems indeed. See also question 20.32.

    ==========

    < 13.24: I'm trying to port this A: Those functions are variously
    < old program. Why do I obsolete; you should
    < get "undefined external" instead:
    < errors for:
    <
    < index? use strchr.
    < rindex? use strrchr.
    < bcopy? use memmove, after
    < interchanging the first and
    < second arguments (see also
    < question 11.25).
    < bcmp? use memcmp.
    < bzero? use memset, with a second
    < argument of 0.

    ==========

    < 15.7: I have a pre-ANSI compiler, without <stdarg.h>. What can I do?
    <
    < A: There's an older header, <varargs.h>, which offers about the
    < same functionality.

    ==========

    < 18.5: How can I shut off the "warning: possible pointer alignment
    < problem" message which lint gives me for each call to malloc()?
    <
    < A: The problem is that traditional versions of lint do not know,
    < and cannot be told, that malloc() "returns a pointer to space
    < suitably aligned for storage of any type of object." It is
    < possible to provide a pseudoimplementation of malloc(), using a
    < #define inside of #ifdef lint, which effectively shuts this
    < warning off, but a simpleminded definition will also suppress
    < meaningful messages about truly incorrect invocations. It may
    < be easier simply to ignore the message, perhaps in an automated
    < way with grep -v. (But don't get in the habit of ignoring too
    < many lint messages, otherwise one day you'll overlook a
    < significant one.)

    ====================

    Steve Summit
     
    Steve Summit, Aug 4, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steve Summit
    Replies:
    0
    Views:
    1,157
    Steve Summit
    Jul 1, 2003
  2. Steve Summit
    Replies:
    0
    Views:
    925
    Steve Summit
    Jul 1, 2003
  3. Steve Summit
    Replies:
    0
    Views:
    586
    Steve Summit
    Aug 1, 2003
  4. Steve Summit
    Replies:
    0
    Views:
    303
    Steve Summit
    Aug 15, 2003
  5. Steve Summit
    Replies:
    0
    Views:
    376
    Steve Summit
    Sep 15, 2003
Loading...

Share This Page