From: scs@adam.mit.edu (Steve Summit)
Subject: Re: Finding RAND_MAX and SEEK_POS (ANSI C)
Organization: none, at the moment
Date: Fri, 6 Nov 1992 23:38:44 GMT

In article <6507@news.duke.edu>, Ted A. Campbell (tcamp@acpub.duke.edu) writes:
> At least two users--in very different parts of the world--have reported
> that their Unix-based ANSI C compilers (one of them was using a version
> of gcc) failed to find the constants SEEK_POS (for fsek()) and
> RAND_MAX (for rand()).  
> 
> My documentation suggests that these constants ought to be defined
> in ANSI-compliant systems...

Indeed they ought.  (In gcc's case, note that its ANSI compliance
is most complete with respect to its parser; gcc often depends on
local #include files and libraries.  If you're using gcc because
it's ANSI-compliant and your vendor-supplied compiler isn't, the
vendor-supplied header files aren't likely to be ANSI-compliant,
either.)

> One user reported that he found SEEK_POS defined in <unistd.h>,
> but I'm not aware of the meaning of this header file. 

It's a standard Posix header; I hadn't realized that both X3.159
and 1003.1 defined the SEEK_* values.  (Posix uses them for lseek().)

> Perhaps someone can reveal these mysteries to me.  Should I include
> default values for these constants (I wouldn't know what they should
> be), or should I simply report that their compilers are broken?

Defaulting them can be tricky.  Read on...

In article <1992Oct30.170950.21366@klaava.Helsinki.FI>, Lars Wirzenius
(wirzeniu@klaava.Helsinki.FI) writes:
> You could provide a "port.h" or "config.h" header, and let the installer
> of the program add defines for these macros to that header.  As a guess,
> SEEK_SET would probably be 0 (especially on Unix systems where fseek is
> built on lseek, which uses 0 for this purpose).

I frequently do things like

	#ifndef SEEK_SET
	#define SEEK_SET 0
	#endif

, because there are plenty of systems out there without these
macros defined.  (Many systems still tell you, on their man
pages, to use 0, 1, or 2 as the third argument to lseek or fseek.)

I was surprised just now to notice that the ANSI C Standard does
*not* specify the numeric values for these macros (unless there's
something I missed), so old code that does

	fseek(fp, 0L, 0);

could theoretically break on a system which (perversely, but
apparently legally) chose to define SEEK_SET as 37.

> If you are not very
> conserned about having an accurate value for RAND_MAX, the value 32767
> should suffice.

I would *not* recommend providing a default value for RAND_MAX.
Any code that is using RAND_MAX at all cares about the value more
than just approximately.  On 16-bit machines, RAND_MAX is usually
32767; on 32-bit machines, it's often 2147483647.  The recommended
way of generating random numbers in a specific range, namely

	rand() / (RAND_MAX / N)

is going to break badly if the value of RAND_MAX is wildly
incorrect.  (It's extremely tempting to duck the RAND_MAX problem
entirely by computing rand() % N, but doing so cannot be
recommended; see a nearby article of mine, or the FAQ list, for
more details.)

If the code finds itself on a system without RAND_MAX locally
#defined, the person doing the installing will have to be asked
to determine the appropriate value somehow.  (Alternately, as
Lars suggested, you could supply your own random number generator,
but doing so sort of defeats the purpose of having one in the
standard library.)

					Steve Summit
					scs@adam.mit.edu
Newsgroups: comp.lang.c