Velocity Reviews > srand(time(NULL))

# srand(time(NULL))

Ioannis Vranos
Guest
Posts: n/a

 03-10-2008
Ben Pfaff wrote:
> http://www.velocityreviews.com/forums/(E-Mail Removed) (Richard Bos) writes:
>
>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>> Richard Bos wrote:
>>>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
>>>> Unless your time_t is a floating point type
>>> The function prototype of srand() is
>>>
>>> void srand(unsigned int seed);
>>>
>>> Whatever time_t is, isn't there an implicit conversion to unsigned?

>> Yes. But the conversion of a floating point value to an integral type
>> causes UB if that value, rounded down, would not fit into the integral
>> type - even if it's an unsigned type.

>
> Additionally, a floating point time value may not be useful as a
> random seed, for example if the time value is always between 0
> and 1. (I am not aware of any systems that do this.)

Also I assume in the floating point case, casting to unsigned is
needless, right?

Keith Thompson
Guest
Posts: n/a

 03-10-2008
Eric Sosman <(E-Mail Removed)> writes:
> Ioannis Vranos wrote:
>> The FAQ mentions:
>>
>> #include <stdlib.h>
>> #include <time.h>
>>
>> srand((unsigned int)time((time_t *)NULL));
>>
>>
>> I think the casting of NULL to "time_t *" is unnecessary in C, since
>> NULL can be assigned to any pointer type without casting (also the
>> conversion of void * to whatever_type * is implicit).
>>
>>
>> Also since the srand() function protype is
>>
>> void srand(unsigned int seed);
>>
>>
>> I think the casting of the return value of time() to unsigned int is
>> unnecessary, since the return value is implicitly converted to the
>> unsigned int argument.

>
> "Unnecessary" is not always the same as "undesirable" --
> do you use indentation to indicate block nesting? -- and the
> question of whether to use or omit these casts is in some
> degree a matter of taste. Myself, I'd omit them. Yet the
> Ten Commandments For C Programmers takes the opposite view
> (Third Commandment), so I am probably in a state of sin.

Reference: <http://www.lysator.liu.se/c/ten-commandments.html>,
written by Henry Spencer.

The original version of this fine document was written, I believe,
before the existence of ANSI C. The Third Commandment is:

Thou shalt cast all function arguments to the expected type if
they are not of that type already, even when thou art convinced
that this is unnecessary, lest they take cruel vengeance upon thee
when thou least expect it.

It may be thought that the radical new blessing of ``prototypes''
might eliminate the need for caution about argument types. Not so,
brethren. Firstly, when confronted with the twisted strangeness of
variable numbers of arguments, the problem returns... and he who
has not kept his faith strong by repeated practice shall surely
fall to this subtle trap. Secondly, the wise men have observed
that reliance on prototypes doth open many doors to strange
errors, and some indeed had hoped that prototypes would be decreed
for purposes of error checking but would not cause implicit
conversions. Lastly, reliance on prototypes causeth great
difficulty in the Real World today, when many cling to the old
ways and the old compilers out of desire or necessity, and no man
knoweth what machine his code may be asked to run on tomorrow.

This was good advice *at the time it was written*. Today, C compilers
that don't support prototypes are vanishingly rare, and this advice is
IMHO obsolete. You still need to be careful when calling variadic
functions; for example, when passing a pointer to printf with the "%p"
format, you should cast it to void*. (Quibbles: If it's already
void*, you don't need to cast it; if it's char*, you can probably get
away without casting it, but you should anyway; if it's a function
pointer, you can't portably print it with "%p" with or without a
cast.)

I'd say the 4th and 9th commandments are similarly obsolete. The 8th
(which mandates K&R brace style) is something that I *wish* everyone
obeyed, but if you're working under a coding standard that requires
some other style, it's more important to be consistent with that, and
with the existing code, than to use the (IMHO better) K&R style. The
only thing worse than code that uses an ugly brace style is code that
uses a mixture of different brace styles.

The remaining Commandments are still good advice today.

In particular, the Eight Commandment includes one of the best pieces
of programming advice I've ever seen, even if you disagree with the
premise that K&R defined the One True Brace Style:

... for thy creativity is better used in solving problems than in
creating beautiful new impediments to understanding.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Richard Heathfield
Guest
Posts: n/a

 03-10-2008
Keith Thompson said:

<snip>
>
> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
> obsolete. The 8th
> (which mandates K&R brace style) is something that I *wish* everyone
> obeyed,

Fortunately, your wishing well is broken. K&R style is *dire*.

Cue the Brace Wars.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

Keith Thompson
Guest
Posts: n/a

 03-10-2008
Ioannis Vranos <(E-Mail Removed)> writes:
> Ben Pfaff wrote:
>> (E-Mail Removed) (Richard Bos) writes:
>>
>>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>>> Richard Bos wrote:
>>>>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
>>>>> Unless your time_t is a floating point type
>>>> The function prototype of srand() is
>>>>
>>>> void srand(unsigned int seed);
>>>>
>>>> Whatever time_t is, isn't there an implicit conversion to unsigned?
>>> Yes. But the conversion of a floating point value to an integral type
>>> causes UB if that value, rounded down, would not fit into the integral
>>> type - even if it's an unsigned type.

>>
>> Additionally, a floating point time value may not be useful as a
>> random seed, for example if the time value is always between 0
>> and 1. (I am not aware of any systems that do this.)

>
> Also I assume in the floating point case, casting to unsigned is
> needless, right?

Correct; the conversion is implicit for any arithmetic type (which
time_t is guaranteed to be). If time_t is a floating-point type, then
other problems appear: if the result of time() doesn't vary outside a
small range, then you won't get much variation in seed values, and if
it can go outside the range 0 .. UINT_MAX, the behavior of the
conversion can be undefined.

In theory, you could even have problems with an integer time_t.
Imagine that unsigned int is 32 bits, and time_t is a 64-bit integer
type whose high-order 32 bits represent time in seconds and whose
low-order 32 bits represent fractions of a second. Imagine further
that the underlying system clock can only represent whole seconds, so
the low-order 32 bits are always 0. Then converting *any* time_t
value returned by time() to unsigned int will yield 0.

Ben Pfaff's solution (treating the time_t result as an array of
unsigned char and hashing it) avoids all these problems, none of which
are likely but all of which are allowed by the standard.

In practice, using srand(time(NULL)) is likely to be good enough for a
quick-and-dirty program, and is unlikely to break in any of the above
described ways on any system you're likely to run into in real life.
On the other hand, the implementation-provided rand() function is
typically not very good; if you want *good* random numbers, you should
use some other technique. <HANDWAVE>See the literature for
details.</HANDWAVE>

he says:

Say, you're right. That's a last vestige of my PDP-11/V7/K&R C
days -- I thought I'd stamped those all out.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson
Guest
Posts: n/a

 03-10-2008
Richard Heathfield <(E-Mail Removed)> writes:
> Keith Thompson said:
> <snip>
>>
>> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
>> obsolete. The 8th
>> (which mandates K&R brace style) is something that I *wish* everyone
>> obeyed,

>
> Fortunately, your wishing well is broken. K&R style is *dire*.
>
> Cue the Brace Wars.
>
> <snip>

NOOOOOOOOOOO!!!!!!!

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Richard Heathfield
Guest
Posts: n/a

 03-10-2008
Keith Thompson said:

<snip>

> Ben Pfaff's solution (treating the time_t result as an array of
> unsigned char and hashing it) avoids all these problems,

As Ben would be the first to acknowledge, that was actually Lawrence
Kirby's solution.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

Ben Pfaff
Guest
Posts: n/a

 03-10-2008
Ioannis Vranos <(E-Mail Removed)> writes:

> Ben Pfaff wrote:
>> (E-Mail Removed) (Richard Bos) writes:
>>
>>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>>> Richard Bos wrote:
>>>>> Ioannis Vranos <(E-Mail Removed)> wrote:
>>>>>> Is srand(time(NULL)); an effective solution for seeding rand(),
>>>>> Unless your time_t is a floating point type
>>>> The function prototype of srand() is
>>>>
>>>> void srand(unsigned int seed);
>>>>
>>>> Whatever time_t is, isn't there an implicit conversion to unsigned?
>>> Yes. But the conversion of a floating point value to an integral type
>>> causes UB if that value, rounded down, would not fit into the integral
>>> type - even if it's an unsigned type.

>>
>> Additionally, a floating point time value may not be useful as a
>> random seed, for example if the time value is always between 0
>> and 1. (I am not aware of any systems that do this.)

>
> Also I assume in the floating point case, casting to unsigned is
> needless, right?

Casting a floating-point value to unsigned int will have the same
effect as allowing it to be implicitly converted to unsigned int
by omitting the cast when a prototype of srand() is visible, so a
cast to unsigned int would not be useful.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}

Ben Pfaff
Guest
Posts: n/a

 03-10-2008
Keith Thompson <(E-Mail Removed)> writes:

> he says:
>
> Say, you're right. That's a last vestige of my PDP-11/V7/K&R C
> days -- I thought I'd stamped those all out.

It's very odd to see the cast in the online FAQ, because the text
version that I keep on my local file system, which says it was
last modified February 7, 1999, omits the cast. Odd that it was
apparently (re?)introduced after that.

I should really update my local copy.
--
Ben Pfaff
http://benpfaff.org

Morris Dovey
Guest
Posts: n/a

 03-10-2008
Richard wrote:
>
> Richard Heathfield <(E-Mail Removed)> writes:
>
> > Keith Thompson said:
> >
> > <snip>
> >>
> >> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
> >> obsolete. The 8th
> >> (which mandates K&R brace style) is something that I *wish* everyone
> >> obeyed,

> >
> > Fortunately, your wishing well is broken. K&R style is *dire*.
> >
> > Cue the Brace Wars.
> >
> > <snip>

>
> K&R style is easily the most maintainable and easiest on the eye I have
> ever used. It just "makes sense. header, body, footer. e.g
>
> if(expr){
> expr;
> }

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto/

Antoninus Twink
Guest
Posts: n/a

 03-10-2008
On 10 Mar 2008 at 16:42, Richard Heathfield wrote:
> Keith Thompson said:
>
><snip>
>>
>> I'd say [Henry Spencer's] 4th and 9th commandments are similarly
>> obsolete. The 8th
>> (which mandates K&R brace style) is something that I *wish* everyone
>> obeyed,

>
> Fortunately, your wishing well is broken. K&R style is *dire*.
>
> Cue the Brace Wars.

The familiar Heathfield combination of minimal taste and maximal
polemic...