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

S

Steve Summit

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.
---

< Insight, from ParaSoft Corporation, 2500 E. Foothill
< Blvd., Pasadena, CA 91107, USA, 818-792-9941,
< (e-mail address removed) .
---
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 ,
< (e-mail address removed) .
< (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, (e-mail address removed), 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, (e-mail address removed) .
---
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/.
---

< 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
< (e-mail address removed)
---
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 .
---

< 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 .
---

< 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/
---
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
and assumes that the double-quote character " has the said:
(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, (e-mail address removed),
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, (e-mail address removed), 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 (e-mail address removed) .
==========
< 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
(e-mail address removed)
 
S

Steve Summit

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.
---

< Insight, from ParaSoft Corporation, 2500 E. Foothill
< Blvd., Pasadena, CA 91107, USA, 818-792-9941,
< (e-mail address removed) .
---
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 ,
< (e-mail address removed) .
< (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, (e-mail address removed), 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, (e-mail address removed) .
---
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/.
---

< 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
< (e-mail address removed)
---
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 .
---

< 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 .
---

< 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/
---
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
and assumes that the double-quote character " has the said:
(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, (e-mail address removed),
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, (e-mail address removed), 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 (e-mail address removed) .
==========
< 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
(e-mail address removed)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top