From: scs@adam.mit.edu (Steve Summit)
Subject: comp.lang.c Changes to Answers to Frequently Asked Questions (FAQ)
Followup-To: poster
Supersedes: <1992Jun1.040025.15906@athena.mit.edu>
Reply-To: scs@adam.mit.edu
X-Archive-Name: C-faq/diff
Organization: none, at the moment
Date: Thu, 1 Oct 1992 21:08:14 GMT

Archive-name: C-faq/diff

This article contains changes between the previous revision of
the comp.lang.c frequently-asked questions list (posted on
September 1, last modified on May 30) and the new one.  (Do _not_
worry if you have not seen the new one yet; it's coming up next.)
As usual, these diffs have been edited for readability, and are
not suitable for use with the patch program.

You may notice that with this release the FAQ list subsections
have been almost completely rearranged and renumbered.  (Be
careful if you have gotten into the habit of referring people to
section N of the FAQ list.)  The existing arrangement had arisen
somewhat haphazardly, and I have been meaning for some time to
rearrange things.  (I can't say that the new arrangement makes
perfect sense, either.)

Since I've abandoned restraint and added a number of new
questions, the list is now up to 110K or so.  I'll continue to
issue feeble little disclaimers and apologies for this
transgression against the recommended 64K article size limit, and
invite anyone who is adversely affected by this policy to let me
know, because without a concrete reason I'm less and less likely
to do anything about it.

==========
< [Last modified May 30, 1992 by scs.]
---
> [Last modified October 1, 1992 by scs.]
==========
<	 3. Expressions
<	 4. ANSI C
<	 5. C Preprocessor
<	 6. Variable-Length Argument Lists
<	 7. Lint
<	 8. Memory Allocation
<	 9. Structures
	10. Declarations
<	11. Boolean Expressions and Variables
<	12. System Dependencies
<	13. Stdio
<	14. Library Subroutines
<	15. Style
<	16. Miscellaneous (Fortran to C converters, YACC grammars, etc.)
---
>	 3. Memory Allocation
>	 4. Expressions
>	 5. ANSI C
>	 6. C Preprocessor
>	 7. Variable-Length Argument Lists
>	 8. Boolean Expressions and Variables
>	 9. Structs, Enums, and Unions
	10. Declarations
>	11. Stdio
>	12. Library Subroutines
>	13. Lint
>	14. Style
>	15. Floating Point
>	16. System Dependencies
>	17. Miscellaneous (Fortran to C converters, YACC grammars, etc.)
==========
	5.	The ASCII null character (NUL), which does have all bits
		zero, but has no relation to the null pointer except in
<		name.  Since this character terminates strings in C, an
<		otherwise empty string may be called...

<	6.	The "null string," consisting only of the terminating
<		'\0'.  This term is best avoided, because it could be
<		construed as having something to do with null pointers,
<		which brings us full circle...
---
		zero, but has no relation to the null pointer except in
>		name; and...

>	6.	The "null string," which is another name for an empty
>		string.  The term "null string" can be confusing in C
>		(and should perhaps be avoided), because it involves a
>		null ('\0') character, but not a null pointer, which
>		brings us full circle...
==========
> 2.6:	Why doesn't sizeof(array) work when the array is a function
>	parameter?
>
> A:	The compiler pretends that the array parameter was declared as a
>	pointer (see question 2.4), and sizeof reports the size of the
>	pointer.
==========
>	Finally, you can use pointers-to-arrays:
>
>		int (*array)[NCOLUMNS] =
>			(int (*)[NCOLUMNS])malloc(nrows * sizeof(*array));
>
>	, but the syntax gets horrific and all but one dimension must be
>	known at compile time.
>
>	With all of these techniques, you may of course need to remember
>	to free the arrays (which may take several steps) when they are
>	no longer needed.  You must also be extremely cautious when
>	passing dynamically-allocated arrays down to other subroutines,
>	if those subroutines are also to accept conventional,
>	statically-allocated arrays (see question 2.9).
==========
> 2.13:	I passed a pointer to a subroutine which initialized it:
>
>		main()
>		{
>			int *ip;
>			f(ip);
>			return 0;
>		}
>
>		void f(ip)
>		int *ip;
>		{
>			static int dummy;
>			ip = &i;
>			*ip = 5;
>		}
>
>	, but the pointer in the caller was unchanged.
>
> A:	Did the subroutine try to initialize the pointer itself, or just
>	what it pointed to?  Remember that arguments in C are passed by
>	value.  The called subroutine altered only the passed copy of
>	the pointer.  You'll want to pass the address of the pointer
>	(the subroutine will end up accepting a pointer-to-a-pointer).
==========
	such as the above are ever accepted.)  Say what you mean: use

		p = (char *)((int *)p + 1);
>
>	, or simply
>
>		p += sizeof(int);
==========
> 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.
==========
		American National Standards Institute
<		1430 Broadway
<		New York, NY  10018  USA
---
>		11 W. 42nd St., 13th floor
>		New York, NY  10036  USA
		(+1) 212 642 4900
==========
>	The GNU GhostScript package comes with a little program called
>	ansi2knr.
==========
> 5.11:	My compiler is rejecting the simplest possible test programs,
>	with all kinds of syntax errors.
>
> A:	Perhaps it is a pre-ANSI compiler, unable to accept function
>	prototypes and the like.
>
> 5.12:	Why won't the Frobozz Magic C Compiler, which claims to be ANSI
>	compliant, accept this code?  I know that the code is ANSI,
>	because gcc accepts it.
>
> A:	Most compilers support a few non-Standard extensions, gcc more
>	so than most.  Are you sure that the code being rejected doesn't
>	rely on such an extension?  It is usually a bad idea to try to
>	determine language properties, especially pertaining to the ANSI
>	Standard, by performing experiments with a particular compiler.
==========
A:	cpp is not intended as a general-purpose preprocessor.  Rather
	than forcing it to do something inappropriate, consider writing
	your own little special-purpose preprocessing tool, instead.
	You can easily get a utility like make(1) to run it for you
	automatically.

>	If you are trying to preprocess something other than C, consider
>	using a general-purpose preprocessor (such as m4).
==========
> 7.5:	How can I call a function with an argument list built up at run
>	time?
>
> A:	There is no guaranteed or portable way to do this.  If you're
>	curious, ask this list's editor, who has a few wacky ideas you
>	could try...  (See also question 16.10.)
==========
< Section 9. Structures
---
> Section 9. Structs, Enums, and Unions
==========
> 9.9:	Why does sizeof report a larger size than I expect for a
>	structure type, as if there was padding at the end?
>
> A:	Structures may have this padding, so that alignment properties
>	will be preserved when an array of contiguous structures is
>	allocated.
>
> 9.10:	How can I turn off structure padding, so that I can get a struct
>	to conform to an externally-imposed storage layout?
>
> A:	Your compiler may provide an extension to give you this control
>	(perhaps a #pragma), but there is no standard method.  See also
>	question 17.2.
>
> 9.11:	Can I initialize unions?
>
> A:	ANSI Standard C allows an initializer for the first member of a
>	union.  There is no standard way of initializing the other
>	members (nor, under a pre-ANSI compiler, is there generally any
>	way of initializing any of them).
==========
	int.  If well-defined overflow characteristics are important
	and/or negative values are not, use the corresponding unsigned
<	types.  (But beware mixtures of signed and unsigned.)  Similar
---
>	types.  (But beware of mixing signed and unsigned in
>	expressions.)  Similar arguments apply when deciding between
	float and double.
==========
>	If for some reason you need to declare something with an _exact_
>	size (usually the only good reason for doing so is when
>	attempting to conform to some externally-imposted storage
>	layout, but see question 17.2), be sure to encapsulate the
>	choice behind an appropriate typedef.
==========
> 10.4:	I'm building a state machine with a bunch of functions, one for
>	each state.  I want to implement state transitions by having
>	each function return a pointer to the next state function.  I
>	find a limitation in C's declaration mechanism: there's no way
>	to declare these functions as returning a pointer to a function
>	returning a pointer to a function returning a pointer to a
>	function...
>
> A:	You can't do it directly.  Either have the function return a
>	generic function pointer type, and apply a cast before calling
>	through it; or have it return a structure containing only a
>	pointer to a function returning that structure.
==========
> 11.1:	Why doesn't this code:
>
>		char c;
>		while((c = getchar()) != EOF)...
>
>	work?
>
> A:	For one thing, the variable to hold getchar's return value must
>	be an int.  getchar can return all possible character values, as
>	well as EOF.  By passing getchar's return value through a char,
>	either a normal character might be misinterpreted as EOF, or the
>	EOF might be altered and so never seen.
>
>	References: CT&P Sec. 5.1 p. 70.
==========
A:	scanf() was designed for free-format input, which is seldom what
	you want when reading from the keyboard.  In particular, "\n" in
<	a format string means, not to expect a newline, but to read and
<	discard characters as long as each is a whitespace character.
---
>	a format string does _not_ mean to expect a newline, but rather
>	to read and discard characters as long as each is a whitespace
>	character.
==========
	It is usually better to use fgets() to read a whole line, and
<	then use sscanf() or other string functions to parse the line
<	buffer.
---
>	then use sscanf() or other string functions to pick apart the
>	line buffer.
==========
> 11.6:	Once I've used freopen, how can I get the original stdout (or
>	stdin) back?
>
> A:	If you need to switch back and forth, the best all-around
>	solution is not to use freopen in the first place.  Try using
>	your own explicit output (or input) stream variable, which you
>	can reassign at will, while leaving the original stdout (or
>	stdin) undisturbed.
==========
> Section 15. Floating Point
==========
	If the problem isn't that simple, recall that 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
<	completely (i.e. order of operation may be important, and
<	repeated addition is not necessarily equivalent to
<	multiplication).  Underflow or cumulative precision loss is
<	often a problem.
---
>	by no means exact simulation of real number arithmetic.
>	Underflow, cumulative precision loss, and other anomalies are
>	often troublesome.
==========
> 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
>	instance, under Unix, you usually need to add -lm after the
>	source and object files when compiling/linking.
==========
	Turbo C's heuristics for determining whether the program uses
<	floating point are occasionally insufficient, and the programmer
---
>	floating point are insufficient, and the programmer must
	sometimes insert a dummy explicit floating-point call to force
	loading of floating-point support.
==========
	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 cannot be standardized by the C
---
>	operating system in use, and has not been standardized by the C
	language.  Some versions of curses have a cbreak() function
==========
> 16.3:	How can I clear the screen?  How can I print things in inverse
>	video?
>
> A:	Such things depend on the terminal type (or display) you're
>	using.  You will have to use a library such as termcap or
>	curses, or some system-specific routines, to perform these
>	functions.
==========
>	Are you sure you have to determine the file's size in advance?
>	Since the most accurate way of determining the size of a file as
>	a C program will see it is to open the file and read it, perhaps
>	you can rearrange the code to learn the size as it reads.
==========
  16.8:	How can a file be shortened in-place without completely clearing
	or rewriting it?

  A:	BSD systems provide ftruncate(), several others supply chsize(),
	and a few may provide a (possibly undocumented) fcntl option
<	F_FREESP, but there is no truly portable solution.
---
>	F_FREESP.  Under MS-DOS, you can sometimes use
>	write(fd, (char *)NULL, 0).  However, but there is no truly
>	portable solution.
==========
> 16.10: How can I read in an object file and jump to routines in it?
>
> A:	You want a dynamic linker and/or loader.  It is possible to
>	malloc some space and read in object files, but you have to know
>	an awful lot about object file formats, relocation, etc.  Under
>	BSD Unix, you could use system() and ld -A to do the linking for
>	you.  There is also a GNU package called "dld" which takes care
>	of some or all of this.  See also question 7.5.
==========
> 17.3:	How can I return several values from a subroutine?
>
> A:	Either pass pointers which the subroutine can fill in, or have
>	the subroutine return a structure containing the desired values.
>	See also questions 2.13, 3.4, and 9.2.
>
> 17.4:	If I have a char * variable pointing to the name of a function
>	as a string, how can I call that function?
>
> A:	The most straightforward thing to do is maintain a
>	correspondence table of names and function pointers:
>
>		int function1(), function2();
>
>		struct {char *name; int (*funcptr)(); } symtab[] =
>			{
>			"function1",    function1,
>			"function2",    function2,
>			};
>
>	Then, just search the table for the name, and call through the
>	associated function pointer.
==========
< 16.4:	How can I call Fortran (BASIC, Pascal, ADA, lisp) functions from
---
> 17.6:	How can I call FORTRAN (C++, BASIC, Pascal, Ada, LISP) functions
>	from C?  (And vice versa?)
==========
>	In C++, a "C" modifier in an external function declaration
>	indicates that the function is to be called using C calling
>	conventions.
==========
> 17.11: How can I implement sets and/or arrays of bits?
>
> A:	Use arrays of char or int, with a few macros to access the right
>	bit at the right index:
>
>		#include <limits.h>             /* for CHAR_BIT */
>
>		#define Mask(bit) (1 << ((bit) % CHAR_BIT))
>		#define Slot(bit) ((bit) / CHAR_BIT)
>		#define Set(ary, bit) ((ary)[Slot(bit)] |= Mask(bit))
>		#define Test(ary, bit) ((ary)[Slot(bit)] & Mask(bit))
==========
	Before rearranging expressions such as i = i + 1, remember that
	you are dealing with a C compiler, not a keystroke-programmable
<	calculator.  A good compiler will generate identical code for
---
>	calculator.  Any decent compiler will generate identical code
>	for ++i, i += 1, and i = i + 1.  The reasons for using ++i or
==========
< 16.13: What does "Segmentation violation" mean?
<
< A:	It means your program tried to access memory it shouldn't have,
---
> 17.16: 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.
==========
< 16.16: How do you pronounce "char"?  What's that funny name for the "#"
<	character?
<
< A:	You can pronounce the C keyword "char" in at least three ways:
<	like the English words "char," "care," or "car;" 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 most of the other groups they
<	frequently come up in.  You can find lots of information in the
<	net.announce.newusers frequently-asked questions postings, the
<	"jargon file" (also published as _The [New] Hacker's
<	Dictionary_), and the old Usenet ASCII pronunciation list.
==========
> 17.19: What's a good book for learning C?
>
> A:	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.
>
>	This FAQ list's editor maintains a collection of previous
>	answers to this question, which is available upon request.
==========
  Thanks to Jamshid Afshar, Sudheer Apte, Dan Bernstein, Stan Brown, Joe
> Buehler, Burkhard Burow, D'Arcy J.M. Cain, Raymond Chen, Christopher
  Calabrese, James Davies, Norm Diamond, Ray Dunn, Stephen M. Dunn, Bjorn
> Engsig, Dave Gillespie, Samuel Goldstein, Alasdair Grant, Ron Guilmette,
  Doug Gwyn, Tony Hansen, Joe Harrington, Guy Harris, Jos Horsmeier, Blair
> Houghton, Kirk Johnson, Peter Klausler, Andrew Koenig, Tom Koenig, John
  Lauro, Don Libes, Christopher Lott, Tim McDaniel, Evan Manning, Mark
> Moraes, Darren Morby, Richard A. O'Keefe, Hans Olsson, Francois Pinard,
  randall@virginia, Pat Rankin, Rich Salz, Chip Salzenberg, Paul Sand,
  Doug Schmidt, Patricia Shanahan, Peter da Silva, Joshua Simons, Henry
  Spencer, Erik Talvola, Clarke Thatcher, Chris Torek, Goran Uddeborg,
  Wietse Venema, Ed Vielmetti, Larry Virden, Freek Wiedijk, and Dave
  Wolverton, 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.
==========

					Steve Summit
					scs@adam.mit.edu
					scs%adam.mit.edu@mit.edu
					mit-eddie!adam.mit.edu!scs
Newsgroups: comp.lang.c