Changes to Answers to Frequently Asked Questions (FAQ) on comp.lang.c
Steve Summit
scs at adam.mit.edu
Sat Dec 1 16:00:48 AEST 1990
This article contains changes between the previous posting of
the frequently-asked questions list (November 1) and the new one.
(Do _not_ worry if you have not seen the new one yet; it's coming
up next.)
(These diffs have been edited for readability and are not suitable
for the patch program.)
< [Last modified 10/31/90 by scs.]
---
> [Last modified 11/30/90 by scs.]
==========
< (On some machines the internal value is 0; on others it is not.)
---
> (On some machines the internal value is all-bits-0; on others it is
> not.)
==========
< which may be different for different pointer types. The actual
< values should be of concern only to compiler writers.
---
> which may or may not be all-bits-0 and which may be different
> for different pointer types. The actual values should be of
> concern only to compiler writers.
==========
< confuses you, don't use it; many people have concluded that the
---
> bothers you, don't use it; many people have concluded that the
==========
< A: Much of the confusion surrounding pointers in C can be traced to
< this statement.
---
> A: Much of the confusion surrounding pointers in C can be traced to a
> misunderstanding of this statement.
==========
< multidimensional arrays. (See the question above.)
---
> multidimensional arrays, if at all. (See question 18 above.) When
> people say "pointer to array" casually, they usually mean "pointer
> to array's first element," which is the more useful type.
==========
< resulting "ragged" array often saves space, although it is not
---
> resulting "ragged" array can save space, although it is not
==========
< accessing array[i, j] with array[i * ncolumns + j].
---
> accessing the i,jth element with array[i * ncolumns + j].
==========
< The ANSI C standard declares that code which contains such ambiguous
< or undefined side effects is not merely undefined, but illegal.
---
> The behavior of code which contains such ambiguous or undefined side
> effects has always been undefined.
==========
< committee, X3J11, to standardize the C language. After a long and
< arduous process, the committee's work was finally ratified as an
---
> committee, X3J11, to standardize the C language. After a long,
> arduous process, including several widespread public reviews, the
> committee's work was finally ratified as an American National
==========
> 27. Why does the ANSI Standard not guarantee more than six monocase
> characters for external identifier significance?
>
> A: The main problem is older linkers which are neither under the
> control of the ANSI standard nor the C compiler developers on the
> systems which have them. 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
> annoying, but certainly not unbearable, and is marked in the
> Standard as "obsolescent," i.e. a future revision will likely relax
> it.
>
> This concession to current, restrictive linkers really had to be
> made, no matter how vehemently some people oppose it. (The
> Rationale notes that its retention was "most painful.") If you
> disagree, or have thought of a trick by which a compiler burdened
> with a restrictive linker could present the C programmer with the
> appearance of more significance in external identifiers, read the
> excellently-worded X3.159 Rationale, which discusses several such
> schemes and describes why they can't be mandated.
>
> References: ANSI Sec. 3.1.2 p. 21, Sec. 3.9.1 p. 96, Rationale Sec.
> 3.1.2 pp. 19-21.
==========
< a single statement, but with a resultant an extra semicolon) as the
---
> a single statement, but with a resultant extra semicolon) as the if
==========
< The best solution is to use
---
> The traditional solution is to use
==========
< expressions, a simpler technique is to separate them with commas and
< surround them with parentheses.
---
> expressions, with no declarations, another technique is to separate
> them with commas and surround them with parentheses.
==========
< little reason to do so, since portable mechanisms exist.)
---
> little reason to do so, since portable mechanisms exist. If you
> know how to access arguments "by hand," but have access to neither
> <stdarg.h> nor <varargs.h>, you could as easily implement one of
> them, leaving your code portable.)
==========
> Q: But the man page for strcat said that it took two char *'s as
> arguments. How was I supposed to know to allocate things?
>
> A: In general, when using pointers you _always_ have to worry about
> memory allocation, at least to make sure that the compiler is doing
> it for you.
>
> The Synopsis section at the top of a Unix-style man page is often
> misleading. The code fragments presented there are closer to the
> function definition used by the call's implementor than the
> invocation used by the caller. In particular, many routines accept
> pointers (e.g. to strings or structs), yet the caller usually passes
> the address of some object (an array, or an entire struct). Another
> common example is stat().
==========
< required. (Pointers to functions are often chosen precisely to
---
> required. (Pointers to structures are often chosen precisely to
==========
< returns, although this made struct-valued function nonreentrant,
---
> returns, although this made struct-valued functions nonreentrant,
==========
> 46. 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 trick is popular, although Dennis Ritchie has called it
> "unwarranted chumminess with the compiler." It is surprisingly
> difficult to determine whether the ANSI C standard allows or
> disallows it, but it is hard to imagine a compiler or architecture
> for which it wouldn't work.
==========
< being called (i.e. is not followed by a "("), its address is
< implicitly taken, just as is done for arrays.
---
> being called (i.e. is not followed by a "("), it "decays" into a
> pointer (i.e. its address is implicitly taken), analagously to the
> implicit decay of an array into a pointer to its first element.
==========
> 54. I've seen different methods used for calling through functions to
> pointers. Wht's the story?
>
> A: Originally, a pointer to a function had to be "turned into" a "real"
> function, with the * operator (and an extra pair of parentheses, to
> keep the precedence straight), before calling:
>
> int r, f(), (*fp)() = f;
> r = (*fp)();
>
> Another argument says that functions are always called through
> pointers, but that "real" functions decay implicitly into pointers
> and so cause no trouble. This argument, which was adopted by the
> ANSI standard, means that
>
> r = fp();
>
> is legal and works correctly (it has always been unambiguous;
> there's nothing you ever could have done with a function pointer
> except call through it). The explicit * is harmless, and still
> allowed (and recommended, if portability to older compilers is
> important).
>
> References: ANSI Sec. 3.3.2.2 .
==========
< will succeed (if a, in fact, equals b and TRUE is 1), but this code
< is obviously silly.
---
> will work as expected (as long as TRUE is 1), but it is obviously
> silly.
==========
> somewhere anyway; see questions 38 and 39. Don't worry that sprintf
> may be overkill, potentially wasting run time or code space; it
> works well in practice.)
==========
> 69. How can I write data files which can be read on other machines with
> different word size, byte order, or floating point formats?
>
> A: The best solution is to use a text file (usually ASCII), written
> with fprintf and read with fscanf or the like. Be very skeptical of
> arguments that text files are too big, or that reading and writing
> them is too slow. Not only is their efficiency frequently adequate
> in practice, but the advantages of being able to manipulate them
> with standard tools can be overwhelming.
>
> If you must use a binary format, you can improve portability, and
> perhaps take advantage of prewritten I/O libraries, by making use of
> standardized formats such as Sun's XDR or OSI's ASN.1 .
==========
< the techniques for passing arguments correctly are often arcane.
---
> the techniques for passing arguments and ensuring correct run-time
> startup are often arcane.
==========
> 75. My floating-point calculations are acting strangely and giving me
> different answers on different machines.
>
> A: Most digital computers use floating-point formats which provide a
> close but by no means exact simulation of real number arithmetic.
> Among other things, the associative and distributive laws do not
> hold exactly (that is, order of calculation may be important, and
> repeated addition is not necessarily equivalent to multiplication).
>
> Don't assume that floating-point results will be exact, and
> especially don't assume that floating-point values can be compared
> for equality. (Don't stick random "fuzz factors" in, either.)
>
> These problems are no worse for C than they are for any other
> language. Languages usually define floating-point semantics as
> "however the processor does them;" otherwise a compiler for a
> machine without the "right" model would have to do prohibitively
> expensive emulations.
>
> This article cannot begin to list the pitfalls associated with, and
> workarounds appropriate for, floating-point work. A good
> programming text should cover the basics. (Beware that subtle
> problems can occupy numerical analysts for years.)
>
> References: K&P Sec. 6 pp. 115-8.
==========
> 79. What's the best style for code layout in C?
>
> A: K&R, while providing the example most often copied, also supply a
> good excuse for avoiding it:
>
> The position of braces is less important; we have
> chosen one of several popular styles. Pick a style
> that suits you, then use it consistently.
>
> It is more important that the layout chosen be consistent (with
> itself, and with nearby or common code) than that it be "perfect."
> If your coding environment (i.e. co-workers or company policy) does
> not suggest a style, and you don't feel like inventing your own,
> just copy K&R. (The tradeoffs between various indenting and brace
> placement options can be exhaustively and minutely examined, but
> don't warrant repetition here.)
>
> Reference: K&R I Sec. 1.2 p. 10.
==========
> 81. How do you pronounce "char"? What's that funny name for the "#"
> character?
>
> A: You can make "char" rhyme with "far" or "bear;" the choice is
> arbitrary. Bell Labs once proposed the (now obsolete) term
> "octothorpe" for the "#" character.
>
> Trivia questions like these aren't any more pertinent for
> comp.lang.c than they are for any of the other groups they
> frequently come up in. The "jargon file" (also published as _The
> Hacker's Dictionary_), contains lots of tidbits like these, as does
> the official Usenet ASCII pronunciation list, maintained by Maarten
> Litmaath. (The pronunciation list also appears in the jargon file
> under ASCII, as well as in the comp.unix frequently-asked questions
> list.)
==========
> Thanks to Mark Brader, Joe Buehler, Raymond Chen, Christopher Calabrese,
> Norm Diamond, Ray Dunn, Stephen M. Dunn, Bjorn Engsig, Doug Gwyn, Tony
> Hansen, Joe Harrington, Guy Harris, Karl Heuer, Blair Houghton, Kirk
> Johnson, Andrew Koenig, John Lauro, Christopher Lott, Evan Manning, Mark
> Moraes, Francois Pinard, randall at virginia, Rich Salz, Paul Sand,
> Patricia Shanahan, Joshua Simons, Henry Spencer, Erik Talvola, Clarke
> Thatcher, Chris Torek, and Freek Wiedijk, who have contributed,
Steve Summit
scs at adam.mit.edu
scs%adam.mit.edu at mit.edu
mit-eddie!adam!scs
More information about the Comp.lang.c
mailing list