Changes to Answers to Frequently Asked Questions on comp.lang.c
Steve Summit
scs at adam.mit.edu
Fri Jun 1 21:01:58 AEST 1990
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 at adam.mit.edu, disregarding the From: line in
< this article's header, which may be incorrect.
---
> Send your comments to scs at adam.mit.edu and/or scs%adam.mit.edu at 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 at adam.mit.edu,
< for inclusions in future updates to this list.
---
> attention to. Please send answers you might have to scs at adam.mit.edu
> and/or scs%adam.mit.edu at 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.
More information about the Comp.lang.c
mailing list