[comp.lang.c] Changes to Answers to Frequently Asked Questions on comp.lang.c

scs@adam.mit.edu (Steve Summit) (06/01/90)

46c47,49
< Both exist in several editions.
---
> Both exist in several editions.  Andrew Koenig's book _C Traps and
> Pitfalls_ also covers many of the difficulties frequently discussed
> here.

72,73c75,76
< Send your comments to scs@adam.mit.edu, disregarding the From: line in
< this article's header, which may be incorrect.
---
> Send your comments to scs@adam.mit.edu and/or scs%adam.mit.edu@mit.edu;
> this article's From: line may be incorrect.

82,87c85,91
<     a special value -- "null" -- which is distinguishable from all other
<     pointer values and which is not the address of any object.  That is,
<     the address-of operator & will never "return" null, nor will malloc.
<     Note that there is a null pointer for each pointer type, and that
<     different pointer types (e.g. char * and int *) may have _different_
<     null pointers.
---
>     a special value -- the "null pointer" -- which is distinguishable
>     from all other pointer values and which is not the address of any
>     object.  That is, the address-of operator & will never "return" a
>     null pointer, nor will a successful call to malloc.  (malloc returns
>     a null pointer when it fails, and this is a typical use of null
>     pointers: as a "special" pointer value with some other meaning,
>     usually "not allocated" or "not pointing anywhere yet.")

88a93,106
>     Although a null pointer does not "point anywhere," it is different
>     from an uninitialized pointer, about which we cannot say where it
>     points.  A null pointer points explicitly nowhere (i.e. not at any
>     object); an uninitialized pointer might point anywhere (at some
>     random object, or at a garbage or unallocated address).  See also
>     question 29.
> 
>     As mentioned in the definition above, there is a null pointer for
>     each pointer type, and the internal values of null pointers for
>     different types may be different.  Although programmers need not
>     know the internal values, the compiler must always be informed which
>     null pointer is required, so it can make the distinction if
>     necessary (see below).

150c169,171
<     apply to pointers to functions.
---
>     apply to pointers to functions.  (Any object pointer may be cast to
>     the "universal" pointer type void *, or char * under a pre-ANSI
>     compiler, when heterogeneous pointers must be passed around.)

169,171c191,194
<     doing so sends the wrong stylistic message.  In particular, do not
<     use NULL when the ASCII nul character is desired.  Provide your own
<     definition
---
>     doing so sends the wrong stylistic message.  (The ANSI #definition
>     of NULL is allowed to be (void *)0, which will not work in non-
>     pointer contexts.)  In particular, do not use NULL when the ASCII
>     nul character is desired.  Provide your own definition

183,186c207,209
< A:  Until now, no mention has been made of the internal representation
<     of the null pointer.  Programmers should never need to know the
<     details of this representation, because it is normally taken care of
<     by the compiler.  If a machine uses a nonzero bit pattern for null
---
> A:  Programmers should never need to know the internal representation(s)
>     of null pointers, because they are normally taken care of by the
>     compiler.  If a machine uses a nonzero bit pattern for null

287a315,332
>     When the phrase "null pointer" is casually used, one of three things
>     may be meant:
> 
>     1.   The internal (or run-time) representation of null pointers,
>          which may be different for different pointer types.  The actual
>          values should be of concern only to compiler writers.  Authors
>          of C programs never see them, since they use...
> 
>     2.   The source code syntax for null pointers, which is the single
>          character '0'.  It is often hidden behind...
> 
>     3.   The NULL macro, which is #defined to be "0" or "(void *)0".
> 
>     This article always uses the phrase "null pointer" for sense 1, the
>     character '0' for sense 2, and the capitalized word "NULL" for
>     sense 3.

295c340,342
<     so because the value might change, or on some weird machine.
---
>     because the value might change later, or on some weird machine.
>     Furthermore, the distinction between the three uses of the term
>     "null" (listed above) is often overlooked.

308a356,370
> 13. I'm still confused.  I just can't understand all this null pointer
>     stuff.
> 
> A:  Follow these two simple rules:
> 
>     1.   When you want to refer to a null pointer in source code, use
>          "0" or "NULL".
> 
>     2.   If the usage of "0" or "NULL" is in a function call, cast it to
>          the pointer type expected by the function being called.
> 
>     Everything else has to do with other people's confusion, or with the
>     internal representation of null pointers, which you shouldn't need
>     to know.

402c464,465
<     National Standard, X3.159-1989, in the spring of 1990.  For the most
---
>     National Standard, X3.159-1989, on December 14, 1989, and published
>     in the spring of 1990.  For the most part, ANSI C standardizes

428a491,520
> 20. Does anyone have a tool for converting old-style C programs to ANSI
>     C, or for automatically generating prototypes?
> 
> A:  There are several such programs, many in the public domain.  Check
>     your nearest comp.sources archive.  (See also question 51.)
> 
> 21. My ANSI compiler complains about a mismatch when it sees
> 
>          extern int blort(float);
>          int blort(x)
>          float x;
>          {...
> 
> A:  You have mixed the new-style declaration "extern int blort(float);"
>     with the old-style definition "int blort(x) float x;".  Old C
>     silently promoted doubles to floats when passing them as arguments,
>     and made a corresponding silent change to formal argument
>     declarations, so the old-style definition actually says that blort
>     takes a double.
> 
>     The problem can be fixed either by using new-style syntax
>     consistently in the definition:
> 
>          int blort(float x) { ... }
> 
>     or by changing the new-style declaration to match the old-style
>     definition:
> 
>          extern int blort(double);

448a540,549
> 23. I'm getting strange syntax errors inside code which I've #ifdeffed
>     out.
> 
> A:  Under ANSI C, the text inside a "turned off" #if, #ifdef, or #ifndef
>     must still consist of "valid preprocessing tokens."  This means that
>     there must be no unterminated comments or quotes (note particularly
>     that an apostrophe within a contracted word looks like the beginning
>     of a character constant) and no newlines inside quotes.

484,485c585
<          vstrcat(first, ...)
<          char *first;
---
>          vstrcat(char *first, ...)

547,548c647
<          error(fmt, ...)
<          char *fmt;
---
>          error(char *fmt, ...)

569a669,672
>     change the va_start line to
> 
>          va_start(argp);

727a831,855
> 34. 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.  If you don't have it, a suggested implementation is
> 
>          #define offset(type, mem) ((size_t)(char *)&(((type *)0)->mem))
> 
>     This implementation's use of the null pointer, however, is said not
>     to be completely portable.
> 
>     See the next question for a usage hint.
> 
> 35. 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
> 
>          offsetof(struct a, b)
> 
>     If structp is a pointer to an instance of this structure, and b is
>     an int field with offset as computed above, b's value can be set
>     indirectly with
> 
>          *(int *)((char *)structp + offset) = value;

757a886,889
>     Alternatively, define the typedefs first (using the line just above)
>     and follow it with the full definition of struct node, which can
>     then use the NODEPTR typedef for the "next" field.

795,796c927,928
<     Occasionally it is necessary to precede this couplet with the
<     tentative declaration
---
>     Occasionally it is necessary to precede this couplet with the empty
>     declaration

802a935,938
>     Again, the typedefs could also be defined before, and then used
>     within, the definitions for struct a and struct b.  The problem
>     arises when an attempt is made to define and use a typedef within
>     the same declaration.

823c960
<               cdecl> define p as pointer to function returning pointer to double
---
>               cdecl> declare p as pointer to function returning pointer to double

851c988
<     char will probably save space.)
---
>     char will probably save data space.)

883,884c1020,1024
<     is guaranteed to work (if TRUE is 1), but this code is obviously
<     silly.
---
>     will succeed (if a, in fact, equals b and TRUE is one), but this
>     code is obviously silly.  In general, explicit tests against TRUE
>     and FALSE are undesirable, because some library functions (notably
>     isupper, isalpha, etc.) return, on success, a nonzero value which is
>     _not_ necessarily 1.

888,889c1028,1029
<     ever change.  That "true" is 1 and "false" (and null) 0 is
<     guaranteed by the language.
---
>     ever change.  That "true" is 1 and "false" (and source-code null
>     pointers) 0 is guaranteed by the language.

897,905c1037,1041
< A:  At the present time, there is essentially no difference.  Although
<     many people might have wished otherwise, the ANSI standard says that
<     enums may be freely intermixed with integral types, without
<     warnings.  (If such intermixing were disallowed without explicit
<     casts, judicious use of enums could catch certain programming
<     errors.)  For now, the only advantage of an enum (other than that
<     the numeric values are automatically assigned) is that a debugger
<     may be able to display the symbolic value when enum variables are
<     examined.
---
> A:  At the present time, there is little difference.  Although many
>     people might have wished otherwise, the ANSI standard says that
>     enums may be freely intermixed with integral types, without errors.
>     (If such intermixing were disallowed without explicit casts,
>     judicious use of enums could catch certain programming errors.)
906a1043,1050
>     For now, the advantages of enums (other than that the numeric values
>     are automatically assigned) are that a compiler may generate
>     nonfatal warnings when enums and ints are indiscriminately mixed
>     (such mixing can still be considered bad style even though it is not
>     strictly illegal) or when enum cases are left out of switch
>     statements; and that a debugger may be able to display the symbolic
>     values when enum variables are examined.

919c1063
<     the CBREAK or RAW bits.  Under MS-DOS, use getch().  Under other
---
>     the terminal driver modes.  Under MS-DOS, use getch().  Under other

> 45. How can my program discover the complete pathname to the executable
>     file from which it was invoked?
> 
> A:  Depending on the operating system, argv[0] may contain all or part
>     of the pathname.  (It may also contain nothing.)  You may be able to
>     duplicate the command language interpreter's search path logic to
>     locate the executable if the name in argv[0] is incomplete.
>     However, there is no guaranteed or portable solution.
> 
> 46. How can a process change an environment variable in its caller?
> 
> A:  In general, it cannot.  If the calling process is prepared to listen
>     explicitly for some indication that its environment should be
>     changed, a special-case scheme can be set up.

945c1104,1105
<     is, after a library function has returned an error code).
---
>     is, after a library function that sets errno on error has returned
>     an error code).

947a1107,1117
> 48. My program's prompts and intermediate output don't always show up on
>     my screen, especially when I pipe the output through another
>     program.
> 
> A:  It is best to use an explicit fflush(stdout) at any point within
>     your program at which output should definitely be visible.  Several
>     mechanisms attempt to perform the fflush for you, at the "right
>     time," but they do not always work, particularly when stdout is a
>     pipe rather than a terminal.

964a1133,1134
> 50. I seem to be missing the system header file <sgtty.h>.  Can someone
>     send me a copy?
>
> A:  Standard headers exist in part so that definitions appropriate to
>     your compiler, operating system, and processer can be supplied.  You
>     cannot just pick up a copy of someone else's header file and expect
>     it to work, unless that person uses exactly the same environment.
>     Ask your vendor why the file was not provided (or to send another
>     copy, if you've merely lost it).

970a1151,1153
>     ptoc another comp.sources.unix contribution, this one written in
>          Pascal.
> 
974a1158,1160
>     The comp.sources.unix archives also contain converters between
>     "K&R" C and ANSI C.

978a1164,1175
> 52. Why don't C comments nest?  Are they legal inside quoted strings?
> 
> A:  C comments do not nest.  For this reason, it is usually better to
>     "comment out" large sections of code, which might contain comments,
>     with #ifdef.
> 
>     The character sequences /* and */ are not special within double-
>     quoted strings, and do not therefore introduce comments, because a
>     program (particularly one which is generating C code as output)
>     might want to print them.

1011,1012c1207,1209
< attention to.  Please send answers you might have to scs@adam.mit.edu,
< for inclusions in future updates to this list.
---
> attention to.  Please send answers you might have to scs@adam.mit.edu
> and/or scs%adam.mit.edu@mit.edu, for inclusion in future updates to this
> list.

1015a1213,1215
>     (Preliminary answers are net.sources/ansi.c.grammar.Z on
>     uunet.uu.net, FSF's GNU C compiler grammar, and the appendix to
>     K&R II.)

1023a1217,1218
> 57. Where can I get the "Indian Hills Style Guide" and other coding
>     standards?
>
>     (I know that several of these are available at utzoo, but I don't
>     have the details.)
> 
> 
> Other questions to be added, once I write up the answers (suggestions
> for more are welcome):
> 
> 58. How can I get these public-domain programs?
> 
>     (The answer is mostly to see the periodic postings in the
>     comp.sources groups.)
> 
> 59. How can I find the day of the week given the date?
> 
> 60. What is alloca and why is its use discouraged?
> 
> 
> Thanks to Mark Brader, Joe Buehler, Christopher Calabrese, Stephen M.
> Dunn, Tony Hansen, Blair Houghton, Kirk Johnson, Andrew Koenig, John
> Lauro, Christopher Lott, Rich Salz, and Joshua Simons, who have
> contributed, directly or indirectly, to this article.

1030a1249,1250
> The C code in this article (vstrcat, error, etc.) is public domain and
> may be used without restriction.