Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

1 view
Skip to first unread message

Steve Summit

unread,
Mar 2, 1994, 4:02:32 AM3/2/94
to
Archive-name: C-faq/diff
Comp-lang-c-archive-name: C-FAQ-list.diff

Descending upon your newsfeed like so many lead balloons is an
unaccountably major set of updates to the comp.lang.c FAQ list.
This diff list is about 40K, considerably bigger than the entire
abridged list. If you appreciate these changes and additions and
are feeling frivolous, drop a note to sum...@ocean.washington.edu
and let Melanie (the FAQ list widow) know that my zombie-like
state over the past few days (a *lot* of suggestions and ideas
had accumulated) was not completely without redeeming value. :-)

I am experimenting with a table of contents (i.e. a separate list
of the questions only), which many people have been requesting.
It's nearly 20K by itself (and that's the text from the abridged
questions), so I'm posting it as a separate article. Let me know
if it's useful or how it could be made more useful.

Two of the apparently new questions (17.27 and 17.28) may seem
familiar to those of you with long memories. I had elided them
at one point, in a vain attempt to hold the list to some
reasonable size, but since that's now clearly a lost cause, I
might as well re-enable them. (The sentence claiming that "Older
copies are obsolete and don't contain much, except the occasional
typo, that the current list doesn't" now becomes true again.)

I have one important caution for those of you who are in the
habit of posting or mailing pointers to this FAQ list: many of
the questions have been renumbered, so it would be a good idea
not to refer to questions solely by number for at least a few
months. (The section numbers, however, remain the same.)

(The following context diffs are edited for readability and are
not suitable for use with patch programs.)

==========
< [Last modified November 3, 1993 by scs.]
---
> [Last modified March 1, 1994 by scs.]
==========
> The old HP 3000 series computers use a different addressing
> scheme for byte addresses than for word addresses; void and char
> pointers therefore have a different representation than an int
> (structure, etc.) pointer to the same address would have.
==========
< Due to the "equivalence of arrays and pointers" (see question
< 2.3), arrays and pointers often seem interchangeable, and in
---
> Due to the so-called equivalence of arrays and pointers (see
> question 2.3), arrays and pointers often seem interchangeable,
==========
2.11: How do I write functions which accept 2-dimensional arrays when
the "width" is not known at compile time?
...
> gcc allows local arrays to be declared having sizes which are
> specified by a function's arguments, but this is a nonstandard
> extension.
==========
> 2.13: Since array references decay to pointers, given
>
> int array[NROWS][NCOLUMNS];
>
> what's the difference between array and &array?
>
> A: Under ANSI/ISO Standard C, &array yields a pointer, of type
> pointer-to-array-of-T, to the entire array (see also question
> 2.12). Under pre-ANSI C, the & in &array generally elicited a
> warning, and was generally ignored. Under all C compilers, an
> unadorned reference to an array yields a pointer, of type
> pointer-to-T, to the array's first element. (See also question
> 2.3.)
==========
2.15: How can I use statically- and dynamically-allocated
multidimensional arrays interchangeably when passing them to
functions?

< A: There is no single perfect method. Given the array and f() as
< declared in question 2.10, f2() as declared in question 2.11,
< array1, array2, array3, and array4 as declared in 2.13, and a
---
> A: There is no single perfect method. Given a function f1()
> similar to the f() of question 2.10, the array as declared in
> question 2.10, f2() as declared in question 2.11, array1,
> array2, array3, and array4 as declared in question 2.14, and a
==========
< f(array, NROWS, NCOLUMNS);
< f(array4, nrows, NCOLUMNS);
---
> f1(array, NROWS, NCOLUMNS);
> f1(array4, nrows, NCOLUMNS);
==========
< f((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
< f((int (*)[NCOLUMNS])array3, nrows, ncolumns);
---
> f1((int (*)[NCOLUMNS])(*array2), nrows, ncolumns);
> f1((int (*)[NCOLUMNS])array3, nrows, ncolumns);
==========
< It must again be noted that passing array to f2() is not
---
> It must again be noted that passing &array[0][0] to f2() is not
strictly conforming; see question 2.11.
==========
2.16: Here's a neat trick: if I write

int realarray[10];
int *array = &realarray[-1];

I can treat "array" as if it were a 1-based array.

< A: Although this technique is attractive (and is used in the book
< Numerical Recipes in C), it does not conform to the C standards.
---
> A: Although this technique is attractive (and was used in old
> editions of the book Numerical Recipes in C), it does not
==========
> 2.19: Can I use a void ** pointer to pass a generic pointer to a
> function by reference?
>
> A: Not portably. There is no generic pointer-to-pointer type in C.
> void * acts as a generic pointer only because conversions are
> applied automatically when other pointer types are assigned to
> and from void *'s; these conversions cannot be performed (the
> correct underlying pointer type is not known) if an attempt is
> made to indirect upon a void ** value which points at something
> other than a void *.
==========
char answer[100], *p;
printf("Type something:\n");
< fgets(answer, 100, stdin);
---
> fgets(answer, sizeof(answer), stdin);
==========
Note that this example also uses fgets instead of gets (always a
< good idea; see question 11.5), so that the size of the array can
< be specified, so that fgets will not overwrite the end of the
< array if the user types an overly-long line. (Unfortunately for
---
> good idea; see question 11.5), allowing the size of the array to
> be specified, so that the end of the array will not be
> overwritten if the user types an overly-long line.
==========
< \n, as gets would.) It would also be possible to use malloc to
< allocate the answer buffer, and/or to parameterize its size
< (#define ANSWERSIZE 100).
---
> delete the trailing \n, as gets would.) It would also be
> possible to use malloc to allocate the answer buffer.
==========
A: Make sure that the memory to which the function returns a
pointer is correctly allocated. The returned pointer should be
to a statically-allocated buffer, or to a buffer passed in by
< the caller, but _not_ to a local array. See also question 17.3.
---
> the caller, but _not_ to a local (auto) array. In other words,
> never do something like
>
> char *f()
> {
> char buf[10];
> /* ... */
> return buf;
> }
>
> One fix would to to declare the buffer as
>
> static char buf[10];
>
> See also question 17.5.
==========
> 3.5: Why does some code carefully cast the values returned by malloc
> to the pointer type being allocated?
>
> A: Before ANSI/ISO Standard C introduced the void * generic pointer
> type, these casts were typically required to silence warnings
> about assignment between incompatible pointer types.
==========
3.6: You can't use dynamically-allocated memory after you free it,
can you?

< A: No. Some early man pages for malloc stated that the contents of
---
> A: No. Some early documentation for malloc stated that the
contents of freed memory was "left undisturbed;" this ill-
advised guarantee was never universal and is not required by
==========
> 3.11: Must I free allocated memory before the program exits?
>
> A: You shouldn't have to. A real operating system definitively
> reclaims all memory when a program exits. Nevertheless, some
> personal computers are said not to reliably recover memory, and
> all that can be inferred from the ANSI/ISO C Standard is that it
> is a "quality of implementation issue."
>
> References: ANSI Sec. 4.10.3.2 .
==========
4.1: Why doesn't this code:

a[i] = i++;

work?

A: The subexpression i++ causes a side effect -- it modifies i's
value -- which leads to undefined behavior if i is also
< referenced elsewhere in the same expression.
---
> referenced elsewhere in the same expression. (Note that
> although the language in K&R suggests that the behavior of this
> expression is unspecified, the ANSI/ISO C Standard makes the
> stronger statement that it is undefined -- see question 5.23.)
==========
> 4.3: I've experimented with the code
>
> int i = 2;
> i = i++;
>
> on several compilers. Some gave i the value 2, some gave 3, but
> one gave 4. I know the behavior is undefined, but how could it
> give 4?
>
> A: Undefined behavior means _anything_ can happen. See question
> 5.23.
==========
> 4.4: People keep saying the behavior is undefined, but I just tried
> it on an ANSI-conforming compiler, and got the results I
> expected.
>
> A: A compiler may do anything it likes when faced with undefined
> behavior (and, within limits, with implementation-defined and
> unspecified behavior), including doing what you expect. It's
> unwise to depend on it, though. See also question 5.18.
==========
> 4.5: Can I use explicit parentheses to force the order of evaluation
> I want? Even if I don't, doesn't precedence dictate it?
>
> A: Operator precedence and explicit parentheses impose only a
> partial ordering on the evaluation of an expression. Consider
> the expression
>
> f() + g() * h()
>
> -- although we know that the multiplication will happen before
> the addition, there is no telling which of the three functions
> will be called first.
==========
4.6: But what about the &&, ||, and comma operators?
I see code like "if((c = getchar()) == EOF || c == '\n')" ...

A: There is a special exception for those operators, (as well as
==========
5.2: How can I get a copy of the Standard?

< A: ANSI X3.159 has been officially superseded by ISO 9899.
< Copies are available from
---
> A: ANSI X3.159 has been officially superseded by ISO 9899. Copies
> are available in the United States from
==========
> In other countries, contact the appropriate national standards
> body, or ISO in Geneva at:
>
> ISO Sales
> Case Postale 56
> CH-1211 Geneve 20
> Switzerland
==========
> The mistitled _Annotated ANSI C Standard_, with annotations by
> Herbert Schildt, contains the full text of ISO 9899; it is
> published by Osborne/McGraw-Hill, ISBN 0-07-881952-0, and sells
> in the U.S. for approximately $40. (It has been suggested that
> the price differential between this work and the official
> standard reflects the value of the annotations.)
==========
A: Two programs, protoize and unprotoize, convert back and forth
between prototyped and "old style" function definitions and
declarations. (These programs do _not_ handle full-blown
translation between "Classic" C and ANSI C.) These programs
< exist as patches to the FSF GNU C compiler, gcc. Look for the
< file protoize-1.39.0.5.Z in pub/gnu at prep.ai.mit.edu
< (18.71.0.38), or at several other FSF archive sites.
---
> were once patches to the FSF GNU C compiler, gcc, but are now
> part of the main gcc distribution; look in pub/gnu at
> prep.ai.mit.edu (18.71.0.38), or at several other FSF archive
> sites.
==========
< The unproto program (/pub/unix/unproto4.shar.Z on
---
> The unproto program (/pub/unix/unproto5.shar.Z on
ftp.win.tue.nl) is a filter which sits between the preprocessor
and the next compiler pass, converting most of ANSI C to
traditional C on-the-fly.
==========
Several prototype generators exist, many as modifications to
lint. Version 3 of CPROTO was posted to comp.sources.misc in
< March, 1992. See also question 17.8.
---
> March, 1992. There is another program called "cextract." See
> also question 17.12.
==========
> 5.5: I don't understand why I can't use const values in initializers
> and array dimensions, as in
>
> const int n = 5;
> int a[n];
>
> A: The const qualifier really means "read-only;" an object so
> qualified is a normal run-time object which cannot (normally) be
> assigned to. The value of a const-qualified object is therefore
> _not_ a constant expression in the full sense of the term. (C
> is unlike C++ in this regard.) When you need a true compile-
> time constant, use a preprocessor #define.
>
> References: ANSI Sec. 3.4 .
==========
A: You have mixed the new-style prototype declaration
"extern int func(float);" with the old-style definition
< "int func(x) float x;". Old C (and ANSI C, in the absence of
< prototypes, and in variable-length argument lists) "widens"
< certain arguments when they are passed to functions. floats are
< promoted to double, and characters and short integers are
< promoted to ints. (The values are automatically converted back
---
> "int func(x) float x;". It is usually safe to mix the two
> styles (see question 5.9), but not in this case. Old C (and
> ANSI C, in the absence of prototypes, and in variable-length
> argument lists) "widens" certain arguments when they are passed
> to functions. floats are promoted to double, and characters and
> short integers are promoted to ints. (For old-style function
> definitions, the values are automatically converted back to the
> corresponding narrower types within the body of the called
> function, if they are declared that way there.)
==========
> 5.9: Can you mix old-style and new-style function syntax?
>
> A: Doing so is perfectly legal, as long as you're careful (see
> especially question 5.8). Note however that old-style syntax is
> marked as obsolescent, and support for it may be removed some
> day.
>
> References: ANSI Secs. 3.7.1, 3.9.5 .
==========
> Declaring a function as void does not merely silence warnings;
> it may also result in a different function call/return sequence,
> incompatible with what the caller (in main's case, the C run-
> time startup code) expects.
==========
> 5.17: Why are some ANSI/ISO Standard library routines showing up as
> undefined, even though I've got an ANSI compiler?
>
> A: It's not unusual to have a compiler available which accepts ANSI
> syntax, but not to have ANSI-compatible header files or run-time
> libraries installed. See also questions 5.16 and 17.2.
==========
> 5.19: Why can't I perform arithmetic on a void * pointer?
>
> A: The compiler doesn't know the size of the pointed-to objects.
> Before performing arithmetic, cast the pointer either to char *
> or to the type you're trying to manipulate.
==========
5.20: Is char a[3] = "abc"; legal? What does it mean?

< A: It is legal, though questionably useful. It declares an array
---
> A: It is legal in ANSI C (and perhaps in a few pre-ANSI systems),
though questionably useful. It declares an array of size three,
initialized with the three characters 'a', 'b', and 'c', without
the usual terminating '\0' character; the array is therefore not
a true C string and cannot be used with strcpy, printf %s, etc.
==========
> 5.22: What does #pragma once mean? I found it in some header files.
>
> A: It is an extension implemented by some preprocessors to help
> make header files idempotent; it is essentially equivalent to
> the #ifndef trick mentioned in question 6.4.
==========
> 5.23: People seem to make a point of distinguishing between
> implementation-defined, unspecified, and undefined behavior.
> What's the difference?
>
> A: Briefly: implementation-defined means that an implementation
> must choose some behavior and document it. Unspecified means
> that an implementation should choose some behavior, but need not
> document it. Undefined means that absolutely anything might
> happen. In no case does the Standard impose requirements; in
> the first two cases it occasionally suggests (and may require a
> choice from among) a small set of likely behaviors.
>
> If you're interested in writing portable code, you can ignore
> the distinctions, as you'll want to avoid code that depends on
> any of the three behaviors.
>
> References: ANSI Sec. 1.6, especially the Rationale.
==========
6.8: I inherited some code which contains far too many #ifdef's for
my taste. How can I preprocess the code to leave only one
conditional compilation set, without running it through cpp and
expanding all of the #include's and #define's as well?

< A: There is a program floating around called unifdef which does
---
> A: There are programs floating around called unifdef, rmifdef, and
> scpp which do exactly this. (See question 17.12.)
==========
A: One popular trick is to define the macro with a single argument,
and call it with a double set of parentheses, which appear to
the preprocessor to indicate a single argument:

#define DEBUG(args) (printf("DEBUG: "), printf args)

if(n != 0) DEBUG(("n is %d\n", n));

The obvious disadvantage is that the caller must always remember
< to use the extra parentheses. Another solution is to use
different macros (DEBUG1, DEBUG2, etc.) depending on the number
< of arguments. (It is often better to use a bona-fide function,
< which can take a variable number of arguments in a well-defined
< way. See questions 7.1 and 7.2 below.)
---
The obvious disadvantage is that the caller must always remember
> to use the extra parentheses. Other solutions are to use
different macros (DEBUG1, DEBUG2, etc.) depending on the number
> of arguments, or to play games with commas:
>
> #define DEBUG(args) (printf("DEBUG: "), printf(args))
> #define _ ,
> DEBUG("i = %d" _ i)
>
> It is often better to use a bona-fide function, which can take a
> variable number of arguments in a well-defined way. See
> questions 7.1 and 7.2.
==========
A: This information is not available to a portable program. Some
old systems provided a nonstandard nargs() function, but its use
was always questionable, since it typically returned the number
< of words passed, not the number of arguments. (Floating point
< values and structures are usually passed as several words.)
---
> of words passed, not the number of arguments. (Structures and
> floating point values are usually passed as several words.)
==========
> 9.6: How can I read/write structs from/to data files?
>
> A: It is relatively straightforward to write a struct out using
> fwrite:
>
> fwrite((char *)&somestruct, sizeof(somestruct), 1, fp);
>
> and a corresponding fread invocation can read it back in.
> However, data files so written will _not_ be very portable (see
> questions 9.11 and 17.3). Note also that on many systems you
> must use the "b" flag when fopening the files.
==========
9.7: I came across some code that declared a structure like this:

struct name
{
int namelen;
char name[1];
};

and then did some tricky allocation to make the name array act
like it had several elements. Is this legal and/or portable?

A: This technique is popular, although Dennis Ritchie has called it
< "unwarranted chumminess with the compiler." An ANSI
< Interpretation Ruling has deemed it not strictly conforming. It
---
A: This technique is popular, although Dennis Ritchie has called it
> "unwarranted chumminess with the C implementation." An ANSI
> Interpretation Ruling has deemed it (more precisely, access
> beyond the declared size of the name field) to be not strictly
> conforming, although a thorough treatment of the arguments
> surrounding the legality of the technique is beyond the scope of
> this list. It seems, however, to be portable to all known
implementations. (Compilers which check array bounds carefully
might issue warnings.)
>
> To be on the safe side, it may be preferable to declare the
> variable-size element very large, rather than very small; in the
> case of the above example:
>
> ...
> char name[MAXSIZE];
> ...
>
> where MAXSIZE is larger than any name which will be stored.
> (The trick so modified is said to be in conformance with the
> Standard.)
>
References: ANSI Rationale Sec. 3.5.4.2 pp. 54-5.
==========
> 9.13: How can I pass constant values to routines which accept struct
> arguments?
>
> A: C has no way of generating anonymous struct values. You will
> have to use a temporary struct variable.
==========
A: Some vendors of C products for 64-bit machines support 64-bit
long ints. Others fear that too much existing code depends on
sizeof(int) == sizeof(long) == 32 bits, and introduce a new 64-
< bit long long int type instead.
---
> bit long long (or __longlong) type instead.
==========
< Vendors who feel compelled to introduce a new long long int type
---
> Vendors who feel compelled to introduce a new, longer integral
type should advertise it as being "at least 64 bits" (which is
truly new; a type traditional C doesn't have), and not "exactly
64 bits."
==========
> 10.6: My compiler is complaining about an invalid redeclaration of a
> function, but I only define it once and call it once.
>
> A: If the first call precedes the definition, the compiler will
> assume a function returns an int. Non-int functions must be
> declared before they are called.
>
> References: K&R I Sec. 4.2 pp. 70; K&R II Sec. 4.2 p. 72; ANSI
> Sec. 3.3.2.2 .
==========
> 10.8: What does extern mean in a function declaration?
>
> A: It can be used as a stylistic hint to indicate that the
> function's definition is probably in another source file, but
> there is no formal difference between
>
> extern int f();
> and
> int f();
>
> References: ANSI Sec. 3.1.2.2 .
==========
> 10.11: What's the auto keyword good for?
>
> A: Nothing; it's obsolete.
==========
11.2: Why doesn't the code scanf("%d", i); work?

< A: You must always pass addresses (in this case, &i) to scanf.
---
> A: scanf needs pointers to the variables it is to fill in; you must
> call scanf("%d", &i);
==========
11.3: Why doesn't this code:

double d;
scanf("%f", &d);

work?

< A: With scanf, use %lf for values of type double, and %f for float.
---
> A: scanf uses %lf for values of type double, and %f for float.
(Note the discrepancy with printf, which uses %f for both double
and float, due to C's default argument promotion rules.)
==========
11.5: Why does everyone say not to use gets()?

A: It cannot be told the size of the buffer it's to read into, so
< it cannot be prevented from overflowing that buffer.
---
> it cannot be prevented from overflowing that buffer. See
> question 3.1 for a code fragment illustrating the replacement of
> gets() with fgets().
==========
12.2: I'm trying to sort an array of strings with qsort, using strcmp
as the comparison function, but it's not working.

A: By "array of strings" you probably mean "array of pointers to
char." The arguments to qsort's comparison function are
pointers to the objects being sorted, in this case, pointers to
pointers to char. (strcmp, of course, accepts simple pointers
to char.)
...
> Beware of the discussion in K&R II Sec. 5.11 pp. 119-20, which
> is not discussing Standard library qsort.
==========
12.3: Now I'm trying to sort an array of structures with qsort. My
comparison routine takes pointers to structures, but the
compiler complains that the function is of the wrong type for
qsort. How can I cast the function pointer to shut off the
warning?

A: The conversions must be in the comparison function, which must
be declared as accepting "generic pointers" (const void * or
> char *) as discussed in question 12.2 above. The code might
> look like
>
> int mystructcmp(p1, p2)
> char *p1, *p2; /* const void * for ANSI C */
> {
> struct mystruct *sp1 = (struct mystruct *)p1;
> struct mystruct *sp2 = (struct mystruct *)p2;
> /* now compare sp1->whatever and *sp2-> ... */
> }
>
> (If, on the other hand, you're sorting pointers to structures,
> you'll need indirection, as in question 12.2:
> sp1 = *(struct mystruct **)p1 .)
==========
Converting a string to a time_t is harder, because of the wide
< variety of date and time formats which should be parsed.
< Public-domain routines have been written for performing this
< function (see, for example, the file partime.c, widely
< distributed with the RCS package), but they are less likely to
< become standardized.
---
> variety of date and time formats which should be parsed. Some
> systems provide a strptime function; another popular routine is
> partime (widely distributed with the RCS package), but these are
> less likely to become standardized.
==========
> 12.7: How can I add n days to a date? How can I find the difference
> between two dates?
>
> A: The ANSI/ISO Standard C mktime and difftime functions provide
> support for both problems. mktime accepts non-normalized dates,
> so it is straightforward to take a filled in struct tm, add or
> subtract from the tm_mday field, and call mktime to normalize
> the year, month, and day fields (and convert to a time_t value).
> difftime computes the difference, in seconds, between two time_t
> values; mktime can be used to compute time_t values for two
> dates to be subtracted. (Note, however, that these solutions
> only work for dates which can be represented as time_t's.) See
> also questions 12.6 and 17.28.
>
> References: K&R II Sec. B10 p. 256; H&S Secs. 20.4, 20.5
> pp. 361-362; ANSI Secs. 4.12.2.2, 4.12.2.3 .
==========
> 12.9: How can I get random integers in a certain range?
>
> A: The obvious way,
>
> rand() % N
>
> (where N is of course the range) is poor, because the low-order
> bits of many random number generators are distressingly non-
> random. (See question 12.11.) A better method is something
> like
>
> (int)((double)rand() / ((double)RAND_MAX + 1) * N)
>
> If you're worried about using floating point, you could try
>
> rand() / (RAND_MAX / N + 1)
>
> Both methods obviously require knowing RAND_MAX (which ANSI
> defines in <stdlib.h>), and assume that N is much less than
> RAND_MAX.
==========
> 12.13: I keep getting errors due to library routines being undefined,
> but I'm #including all the right header files.
>
> A: In some cases (especially if the routines are nonstandard) you
> may have to explicitly ask for the correct libraries to be
> searched when you link the program. See also question 15.2.
==========
> 12.14: I'm still getting errors due to library routines being
> undefined, even though I'm using -l to request the libraries
> while linking.
>
> A: Many linkers make one pass over the list of object files and
> libraries you specify, and extract from libraries only those
> modules which satisfy references which have so far come up as
> undefined. Therefore, the order in which libraries are listed
> with respect to object files (and each other) is significant;
> usually, you want to search the libraries last (i.e., under
> Unix, put any -l switches towards the end of the command line).
==========
> 12.15: I need some code to do regular expression matching.
>
> A: Look for the regexp library (supplied with many Unix systems),
> or get Henry Spencer's regexp package from cs.toronto.edu in
> pub/regexp.shar.Z (see also question 17.12).
==========
> 12.16: How can I split up a command line into argc and argv, like the
> shell does?
>
> A: Most systems have a routine called strtok.
>
> References: ANSI Sec. 4.11.5.8; K&R II Sec. B3 p. 250; H&S
> Sec. 15.7; PCS p. 178.
==========
15.2: I'm trying to do some simple trig, and I am #including <math.h>,
but I keep getting "undefined: _sin" compilation errors.

< A: Make sure you're linking against the correct math library. For
---
> A: Make sure you're linking with the correct math library. For
==========
> 15.4: How do I round numbers?
>
> A: The simplest and most straightforward way is with code like
>
> (int)(x + 0.5)
>
> This won't work properly for negative numbers, though.
==========
> 15.5: How do I test for IEEE NaN and other special values?
>
> A: Many systems with high-quality IEEE floating-point
> implementations provide facilities (e.g. an isnan() macro) to
> deal with these values cleanly, and the Numerical C Extensions
> Group (NCEG) is working to formally standardize such facilities.
> A crude but usually effective test for NaN is exemplified by
>
> #define isnan(x) ((x) != (x))
>
> although non-IEEE-aware compilers may optimize the test away.
==========
A: Contrary to popular belief and many people's wishes, this is not
a C-related question. (Nor are closely-related questions
concerning the echo of keyboard input.) The delivery of
characters from a "keyboard" to a C program is a function of the
operating system in use, and has not been standardized by the C
language. Some versions of curses have a cbreak() function
< which does what you want. Under UNIX, use ioctl to play with
< the terminal driver modes (CBREAK or RAW under "classic"
< versions; ICANON, c_cc[VMIN] and c_cc[VTIME] under System V or
< Posix systems). Under MS-DOS, use getch(). Under VMS, try the
< Screen Management (SMG$) routines, or curses, or issue low-level
< $QIO's to ask for one character at a time. Under other
---
> which does what you want. If you're specifically trying to read
> a short password without echo, you might try getpass(). Under
> Unix, use ioctl to play with the terminal driver modes (CBREAK
> or RAW under "classic" versions; ICANON, c_cc[VMIN] and
> c_cc[VTIME] under System V or Posix systems). Under MS-DOS, use
> getch(). Under VMS, try the Screen Management (SMG$) routines,
> or curses, or issue low-level $QIO's with the IO$_READVBLK (and
> perhaps IO$M_NOECHO) function codes to ask for one character at
> a time. Under other operating systems, you're on your own.
==========
> 16.7: How can I check whether a file exists? I want to query the user
> if a requested output file already exists.
>
> A: You can try the access() routine, although it's got a few
> problems. (It isn't atomic with respect to the following
> action, and it has anomalies if the program calling it is
> running as root.)
==========
16.8: How can I find out the size of a file, prior to reading it in?
...
> files). Some systems provide routines called filesize or
> filelength.
==========
> 16.12: How can I invoke an operating system command from within a
> program?
>
> A: Use system().
>
> References: K&R II Sec. B6 p. 253; ANSI Sec. 4.10.4.5; H&S
> Sec. 21.2; PCS Sec. 11 p. 179;
==========
> 16.15: How can I do serial ("comm") port I/O?
>
> A: It's system-dependent. Under Unix, you typically open, read,
> and write a device in /dev, and use the facilities of the
> terminal driver to adjust its characteristics. Under MS-DOS,
> you can either use some primitive BIOS interrupts, or (if you
> require decent performance) one of any number of interrupt-
> driven serial I/O packages.
==========
17.1: What can I safely assume about the initial values of variables
which are not explicitly initialized?
...
A: Variables with "static" duration (that is, those declared
outside of functions, and those declared with the storage class
< static), are guaranteed initialized to zero, as if the
< programmer had typed "= 0". Therefore, such variables are
---
> static), are guaranteed initialized (just once, at program
> startup) to zero, as if the programmer had typed "= 0".
==========
> 17.2: This code, straight out of a book, isn't compiling:
>
> f()
> {
> char a[] = "Hello, world!";
> }
>
> A: Perhaps you have a pre-ANSI compiler, which doesn't allow
> initialization of "automatic aggregates" (i.e. non-static local
> arrays and structures). As a workaround, you can make the array
> global or static. (You can always initialize local char *
> variables with string literals, but see question 17.20). See
> also questions 5.16 and 5.17.
==========
> 17.4: How can I delete a line (or record) from the middle of a file?
>
> A: Short of rewriting the file, you probably can't. See also
> question 16.9.
==========
> 17.10: Is C++ a superset of C? Can I use a C++ compiler to compile C
> code?

> A: C++ was derived from C, and is largely based on it, but there
> are some legal C constructs which are not legal C++. (Many C
> programs will nevertheless compile correctly in a C++
> environment.)
==========
> 17.11: I need: A: Look for programs (see also
> question 17.12) named:
>
> a C cross-reference cflow, calls, cscope
> generator
>
> a C beautifier/pretty- cb, indent
> printer
==========
and/or uucp from a central, public-spirited site, such as uunet
(ftp.uu.net, 192.48.96.9). However, this article cannot track
or list all of the available archive sites and how to access
< them. The comp.archives newsgroup contains numerous
---
> them.
>
> Ajay Shah maintains an index of free numerical software; it is
> posted periodically, and available where this FAQ list is
> archived (see question 17.33). The comp.archives newsgroup
==========
< 17.10: Why don't C comments nest? Are they legal inside quoted
strings?
---
> 17.14: Why don't C comments nest? How am I supposed to comment out
> code containing comments? Are comments legal inside quoted
strings?

A: Nested comments would cause more harm than good, mostly because
of the possibility of accidentally leaving comments unclosed by
including the characters "/*" within them. For this reason, it
is usually better to "comment out" large sections of code, which
might contain comments, with #ifdef or #if 0 (but see question
==========
> 17.15: How can I get the ASCII value corresponding to a character, or
> vice versa?
>
> A: In C, characters are represented by small integers corresponding
> to their values (in the machine's character set) so you don't
> need a conversion routine: if you have the character, you have
> its value.
==========
> 17.20: Why does this code:
>
> char *p = "Hello, world!";
> p[0] = tolower(p[0]);
>
> crash?
>
> A: String literals are not necessarily modifiable, except (in
> effect) when they are used as array initializers. Try
>
> char a[] = "Hello, world!";
>
> (For compiling old code, some compilers have a switch
> controlling whether strings are writable or not.) See also
> questions 2.1, 2.2, 2.8, and 17.2.
>
> References: ANSI Sec. 3.1.4 .
==========
17.22: What do "Segmentation violation" and "Bus error" mean?

A: These generally mean that your program tried to access memory it
shouldn't have, invariably as a result of improper pointer use,
< often involving malloc (see question 17.17) or perhaps scanf
< (see question 11.2).
---
> often involving uninitialized or improperly allocated pointers
> (see questions 3.1 and 3.2), or malloc (see question 17.23), or
> perhaps scanf (see question 11.2).
==========
A number of debugging packages exist to help track down malloc
< problems; one popular one is Conor P. Cahill's "dbmalloc".
---
> problems; one popular one is Conor P. Cahill's "dbmalloc,"
> posted to comp.sources.misc in September of 1992. Others are
> "leak," available in volume 27 of the comp.sources.unix
> archives; JMalloc.c and JMalloc.h in Fidonet's C_ECHO Snippets
> (or ask archie; see question 17.12); and MEMDEBUG from
> dorado.crpht.lu in pub/sources/memdebug . See also question
> 17.12.
==========
17.24: Does anyone have a C compiler test suite I can use?

< A: Plum Hall (1 Spruce Ave., Cardiff, NJ 08232, USA) sells one.
---
> A: Plum Hall (formerly in Cardiff, NJ; now in Hawaii) sells one.
==========
< compilers. Kahan's paranoia test, found in netlib on
< research.att.com, strenuously tests a C implementation's
< floating point capabilities.
---
> compilers. Kahan's paranoia test, found in netlib/paranoia on
> netlib.att.com, strenuously tests a C implementation's floating
> point capabilities.
==========
17.25: Where can I get a YACC grammar for C?

A: The definitive grammar is of course the one in the ANSI
< standard. Several copies are floating around; keep your eyes
< open. There is one (due to Jeff Lee) on uunet (see question
< 17.8) in usenet/net.sources/ansi.c.grammar.Z (including a
< companion lexer). Another one, by Jim Roskind, is in
< pub/*grammar* at ics.uci.edu . The FSF's GNU C compiler
---
A: The definitive grammar is of course the one in the ANSI
> standard. Another grammar, by Jim Roskind, is in pub/*grammar*
> at ics.uci.edu . A fleshed-out, working instance of the ANSI
> grammar (due to Jeff Lee) is on uunet (see question 17.12) in
> usenet/net.sources/ansi.c.grammar.Z (including a companion
> lexer). The FSF's GNU C compiler contains a grammar, as does
> the appendix to K&R II.
==========
> 17.26: I need code to parse and evaluate expressions.
>
> A: Two available packages are "defunc," posted to comp.source.misc
> in December, 1993 (V41 i32,33), to alt.sources in January, 1994,
> and available from sunsite.unc.edu in
> pub/packages/development/libraries/defunc-1.3.tar.Z; and
> "parse," at lamont.ldgo.columbia.edu.
==========
> 17.27: I need a sort of an "approximate" strcmp routine, for comparing
> two strings for close, but not necessarily exact, equality.
>
> A: The traditional routine for doing this sort of thing involves
> the "soundex" algorithm, which maps similar-sounding words to
> the same numeric codes. Soundex is described in the Searching
> and Sorting volume of Donald Knuth's classic _The Art of
> Computer Programming_.
==========
> 17.28: How can I find the day of the week given the date?
>
> A: Use mktime (see questions 12.6 and 12.7), or Zeller's
> congruence. Here is one quick implementation posted by Tomohiko
> Sakamoto:
>
> dayofweek(y, m, d) /* 0 = Sunday */
> int y, m, d; /* 1 <= m <= 12, y > 1752 or so */
> {
> static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
> y -= m < 3;
> return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
> }
==========
> 17.29: Will 2000 be a leap year? Is (year % 4 == 0) an accurate test
> for leap years?
>
> A: Yes and no, respectively. The full expression for the Gregorian
> calendar is
>
> year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
>
> See a good astronomical almanac or other reference for details.
==========
> 17.32: Are there any C tutorials on the net?
>
> A: There are at least two of them:
>
> "Notes for C programmers," by Christopher Sawtell,
> available from:
> svr-ftp.eng.cam.ac.uk:misc/sawtell_C.shar
> garbo.uwasa.fi:/pc/c/c-lesson.zip
> oak.oakland.edu:pub/msdos/c/LEARN-C.ZIP
> paris7.jussieu.fr:/contributions/docs
>
> Tim Love's "C for Programmers,"
> available from svr-ftp.eng.cam.ac.uk in the misc directory.
==========
17.33: Where can I get extra copies of this list? What about back
issues?

A: For now, just pull it off the net; it is normally posted to
< comp.lang.c on the first of each month, with an Expiration: line
< which should keep it around all month. It can also be found in
< the newsgroups comp.answers and news.answers . Several sites
< archive news.answers postings and other FAQ lists, including
< this one: two sites are rtfm.mit.edu (directory pub/usenet), and
< ftp.uu.net (directory usenet). The archie server should help
< you find others. See the meta-FAQ list in news.answers for more
< information; see also question 17.8.
---
A: For now, just pull it off the net; it is normally posted to
> comp.lang.c on the first of each month, with an Expires: line
> which should keep it around all month. An abridged version is
> also available (and posted), as is a list of changes
> accompanying each significantly updated version. These lists
> can also be found in the newsgroups comp.answers and
> news.answers . Several sites archive news.answers postings and
> other FAQ lists, including this one: two sites are rtfm.mit.edu
> (directories pub/usenet/news.answers/C-faq/ and
> pub/usenet/comp.lang.c/ ) and ftp.uu.net (directory
> usenet/news.answers/C-faq/ ). The archie server should help you
> find others; query it for "prog C-faq". See the meta-FAQ list
> in news.answers for more information; see also question 17.12.
==========
Acknowledgements

Thanks to Jamshid Afshar, Sudheer Apte, Randall Atkinson, Dan Bernstein,
Vincent Broman, Stan Brown, Joe Buehler, Gordon Burditt, Burkhard Burow,
> Conor P. Cahill, D'Arcy J.M. Cain, Christopher Calabrese, Ian Cargill,
> Paul Carter, Raymond Chen, Jonathan Coxhead, Lee Crawford, Steve Dahmer,
> Andrew Daviel, James Davies, Jutta Degener, Norm Diamond, Jeff Dunlop,
> Ray Dunn, Stephen M. Dunn, Michael J. Eager, Dave Eisen, Bjorn Engsig,
> Chris Flatters, Rod Flores, Alexander Forst, Jeff Francis, Dave
Gillespie, Samuel Goldstein, Alasdair Grant, Ron Guilmette, Doug Gwyn,
> Tony Hansen, Joe Harrington, Guy Harris, Elliotte Rusty Harold, Jos
> Horsmeier, Blair Houghton, Ke Jin, Kirk Johnson, Larry Jones, Kin-ichi
> Kitano, Peter Klausler, Andrew Koenig, Tom Koenig, Ajoy Krishnan T,
> Markus Kuhn, John Lauro, Felix Lee, Mike Lee, Timothy J. Lee, Tony Lee,
> Don Libes, Christopher Lott, Tim Love, Tim McDaniel, Stuart MacMartin,
> John R. MacMillan, Bob Makowski, Evan Manning, Barry Margolin, George
> Matas, Brad Mears, Bill Mitchell, Mark Moraes, Darren Morby, Ken Nakata,
> Landon Curt Noll, David O'Brien, Richard A. O'Keefe, Hans Olsson, Philip
> (lijn...@embl-heidelberg.de), Christopher Phillips, Francois Pinard,
> Dan Pop, Kevin D. Quitt, Pat Rankin, J. M. Rosenstock, Erkki Ruohtula,
> Tomohiko Sakamoto, Rich Salz, Chip Salzenberg, Paul Sand, DaviD
> W. Sanderson, Christopher Sawtell, Paul Schlyter, Doug Schmidt, Rene
> Schmit, Patricia Shanahan, Peter da Silva, Joshua Simons, Henry Spencer,
> David Spuler, Melanie Summit, Erik Talvola, Clarke Thatcher, Wayne
> Throop, Chris Torek, Andrew Tucker, Goran Uddeborg, Rodrigo Vanegas, Jim
> Van Zandt, Wietse Venema, Ed Vielmetti, Larry Virden, Chris Volpe, Mark
> Warren, Larry Weiss, Freek Wiedijk, Lars Wirzenius, Dave Wolverton,
Mitch Wright, Conway Yee, and Zhuo Zang, who have contributed, directly
or indirectly, to this article. Special thanks to Karl Heuer, and
particularly to Mark Brader, who (to borrow a line from Steve Johnson)
have goaded me beyond my inclination, and occasionally beyond my
endurance, in relentless pursuit of a better FAQ list.
==========
< This article is Copyright 1988, 1990-1993 by Steve Summit.
---
> This article is Copyright 1988, 1990-1994 by Steve Summit.
==========

Steve Summit
s...@eskimo.com

0 new messages