Background: I use rand()
, std::rand()
, std::random_shuffle()
and other functions in my code for scientific calculations. To be able to reproduce my results, I always explicitly specify the random seed, and set it via srand()
. That worked fine until recently, when I figured out that libxml2 would also call srand()
lazily on its first usage - which was after my early srand()
call.
I filled in a bug report to libxml2 about its srand()
call, but I got the answer:
Initialize libxml2 first then. That's a perfectly legal call to be made from a library. You should not expect that nobody else calls
srand()
, and the man page nowhere states that usingsrand()
multiple time should be avoided
This is actually my question now. If the general policy is that every lib can/should/will call srand()
, and I can/might also call it here and there, I don't really see how that can be useful at all. Or how is rand()
useful then?
That is why I thought, the general (unwritten) policy is that no lib should ever call srand()
and the application should call it only once in the beginning. (Not taking multi-threading into account. I guess in that case, you anyway should use something different.)
I also tried to research a bit which other libraries actually call srand()
, but I didn't find any. Are there any?
My current workaround is this ugly code:
{
// On the first call to xmlDictCreate,
// libxml2 will initialize some internal randomize system,
// which calls srand(time(NULL)).
// So, do that first call here now, so that we can use our
// own random seed.
xmlDictPtr p = xmlDictCreate();
xmlDictFree(p);
}
srand(my_own_seed);
Probably the only clean solution would be to not use that at all and only to use my own random generator (maybe via C++11 <random>
). But that is not really the question. The question is, who should call srand()
, and if everyone does it, how is rand()
useful then?
srand()
, just by callingrand()
they will also influence the global random generator. – Overcloudsrand_if_not_yet_initialised()
function in the API, but too late for that. Prefer the C++11 versions. – Draissrand()
) is broken. Their answer is just waffling, trying to justify the unjustifiable. For the rest: if you need reproducible random numbers for scientific calculations,rand()
doesn't fill the bill. It's fine for games, or just playing around, but that's about it. Otherwise, in pre-C++11, you implement your own, and in C++11, you use<random>
. (But that doesn't let the library implementers off the hook.) – Doironsrand()
be called before initializing the library. Or simply use their own, private random number generator (in which case, they should provide a means of specifying the seed, so that you can test code which uses the library). – Doiron<random>
is fine if the library doesn't need to support pre-C++11), or ask the user to provide one (likestd::random_shuffle
). – Doironrand()
be appropriate. (Most would require some sort of cryptographically secure RNG. Which means that neitherrand()
nor anything in<random>
would be appropriate.) – Doironrand
and appropriate to recommend new C++11 alternatives, a point that seems to be being overlooked here is that in many single-threaded applications, after callingsrand()
with the same seed, and with the same (if any) external inputs, the execution both in app and library code will be entirely deterministic. Having a library callrand()
changes the global state, but no less predictably that if the higher level app code had done so; if the calls are interspersed in the same way, no harm done. – Draisrand
isn't one)? – Condominiumrand()
is probably used to protect against algorithmic complexity attacks, not for any serious cryptography. – Papal