time(0L) - history of a misconception (was Re: SCO password generator)

Jeff Turner jeff at uf.msc.umn.edu
Wed May 22 17:04:01 AEST 1991


In article <1141 at mwtech.UUCP> martin at mwtech.UUCP (Martin Weitzel) writes:
>In article <588 at sherpa.UUCP> rac at sherpa.UUCP (Roger Cornelius) writes:
>[...]
>>	long seed = time(0L);
>	                 ^^--------- wrong
>	           time((long *)0);
>	                ^^^^^^^^^--- right
>
>Note that the argument to the time system call is a `long *', aka
>pointer to long. Repeat after me: POINTER to long.

You are right -- to ensure portability, you should always pass what is expected
(i.e. a pointer and not a long).  This way, if someday a machine is created 
on which a pointer to a long is a different size then a long, the program will
still work.  However, I don't know of any machines on which the two differ.

Perhaps you are confusing time(0) with time(0L).  Calling time(0) on a 16-bit
machine (e.g. PCs not running 386 UNIX) will push only a 16 bit value onto the
stack instead of the 32 bit address that time() is expecting (and is going to
use).  Since half of the 32-bit address will have a random (and probably
non-zero) value, time() will use it as an address to store the current time
into, and bash your memory or cause range-error core-dump.

I encountered this problem frequently back when I was running uPort's SysV/AT.
I found that passing NULL to time() (or to any other similar function) worked
in all cases as the value of NULL changes with the memory model (i.e. small
memory model defined it simply as 0, whereas large memory model defined it
as 0L).  Of course by definition, passing (long*)0 is the only truely correct
way to pass a long pointer that points to address 0, but that is toooooooo
much to type :-)

-Jeff
---
Jeff Turner                           EMAIL: jeff at msc.edu
Minnesota Supercomputer Center, Inc.  VOICE: (612) 626-0544
Minneapolis, Minnesota  55415           FAX: (612) 624-6550



More information about the Comp.lang.c mailing list