There are two parts to this story.
First, rand
is a pseudorandom number generator. This means it depends on a seed. For a given seed it will always give the same sequence (assuming the same implementation). This makes it not suitable for certain applications where security is of a great concern. But this is not specific to rand
. It’s an issue with any pseudo-random generator. And there are most certainly a lot of classes of problems where a pseudo-random generator is acceptable. A true random generator has its own issues (efficiency, implementation, entropy) so for problems that are not security related most often a pseudo-random generator is used.
So you analyzed your problem and you conclude a pseudo-random generator is the solution. And here we arrive to the real troubles with the C random library (which includes rand
and srand
) that are specific to it and make it obsolete (a.k.a.: the reasons you should never use rand
and the C random library).
-
One issue is that it has a global state (set by
srand
). This makes it impossible to use multiple random engines at the same time. It also greatly complicates multithreaded tasks. -
The most visible problem of it is that it lacks a distribution engine:
rand
gives you a number in interval[0 RAND_MAX]
. It is uniform in this interval, which means that each number in this interval has the same probability to appear. But most often you need a random number in a specific interval. Let’s say[0, 1017]
. A commonly (and naive) used formula isrand() % 1018
. But the issue with this is that unlessRAND_MAX
is an exact multiple of1018
you won’t get an uniform distribution. -
Another issue is the Quality of Implementation of
rand
. There are other answers here detailing this better than I could, so please read them.
In modern C++ you should definitely use the C++ library from <random>
which comes with multiple random well-defined engines and various distributions for integer and floating point types.