2

Is it allowed for srand(0) to have the same effect as srand(1)?

C11, 7.22.2.2 The srand function (empahasis added):

The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand.

However, in glibc srand(0) has the same effect as srand(1):

  /* We must make sure the seed is not 0.  Take arbitrarily 1 in this case.  */
  if (seed == 0)
    seed = 1;

Hence, the same sequence of pseudo-random numbers is returned by subsequent calls to rand, which is confusing.

Extra: We see that in MSVC srand(0) does not have the same effect as srand(1).

pmor
  • 5,392
  • 4
  • 17
  • 36
  • Probably because using 0 as a seed does not produce a good random sequence? (Don't really know). – Jean-Baptiste Yunès Oct 25 '22 at 11:23
  • Is it allowed per C standard for `srand(0)` to have the same effect as `srand(1)`? – pmor Oct 25 '22 at 11:25
  • 1
    The C standard doesn't mention `srand(0)` as a special case. Only that not calling srand is the same as `srand(1)`. – Lundin Oct 25 '22 at 11:41
  • 3
    And nowhere does the standard state that different seeds have to produce different sequences. FWIW `srand(42)` and `srand(1337)` could return the same "random" sequence. – knittl Oct 25 '22 at 11:48
  • 1
    "New sequence" doesn't necessarily mean "unique sequence". – interjay Oct 25 '22 at 11:49
  • 1
    @knittl Even more, per C11 footnote 288 "There are no guarantees as to the quality of the random sequence". Hence, `int rand(void) { return 4; /* chosen by fair dice roll */ }` is allowed. – pmor Oct 25 '22 at 12:29

2 Answers2

5

Is it allowed for srand(0) to have the same effect as srand(1)?

The text you quote from the language spec does not indicate otherwise, nor do I have any other reason to think otherwise. You emphasize the words "new sequence", but that in no way implies that different seeds must produce different sequences.

In fact, the description you quote in no way conditions the newness of the subsequent PRN sequence on the value of the key presented to srand(). Consider this function, then:

void rtest(void) {
    srand(42);
    int x1 = rand();
    srand(42);
    int x2 = rand();
    if (x1 == x2) {
        puts("equal");
    } else {
        puts("unequal");
    }
}

I expect execution of that function to print "equal", and more generally, that an arbitrary number of PRNs generated after the first srand() will be equal to the same number of them generated after the second. In what sense, then, has the second srand() call fulfilled its obligation to use the specified key for a new sequence of PRNs?

The "new" should be understood in the sense of discontinuing use of the current sequence of pseudorandom numbers, and starting to use the one characterized by the specified seed from its beginning, regardless of which sequence that is. There is no requirement that different keys characterize different sequences, though that will affect perceived quality of implementation.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
4

"new sequence" in this case just means a freshly started sequence. Look at the next sentence in C11 §7.22.2.2p2:

If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated.

This means that srand(10); followed by srand(10); creates two new sequences that are guaranteed to be the same, so new doesn't mean "unique" in this context.

Nothing is stopping srand(0) and srand(1) from also being the same sequence.

Artyer
  • 31,034
  • 3
  • 47
  • 75