Corinna Vinschen wrote: > I took a look into POSIX and I'm a bit puzzled now. From > https://pubs.opengroup.org/onlinepubs/9699919799/functions/rand.html
Part of the confusion is that POSIX and ISO C have slightly different wording. This POSIX page says: "The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2017 defers to the ISO C standard." In ISO C 99 § 7.20.2, the only relevant sentence is: "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. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated." In ISO C 11 § 7.22.2 and ISO C 17 § 7.22.2, additionally two sentences were inserted: "The rand function is not required to avoid data races with other calls to pseudo-random sequence generation functions." "The srand function is not required to avoid data races with other calls to pseudo-random sequence generation functions." ISO C 23 (which is still is draft state, but compared to the draft https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf I cannot see any change regarding rand() in the changes summary https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3148.doc) has the same wording. POSIX does not have these two sentences, but instead has: "The rand() function need not be thread-safe." > RATIONAL > > The ISO C standard rand() and srand() functions allow per-process > ^^^^^ (not requires) > > pseudo-random streams shared by all threads. Indeed, "requires" would fit better here, IMO, because the texts of both ISO C and POSIX have multithreading in mind and still talk about "subsequent calls to rand" — which makes a reference to time, but not to threads. > Ok, so, *iff* rand/srand share per-process state, then they have to > use locking to prevent MT interference. ... if the implementor wants to prevent MT interference (which both ISO C and POSIX allows). > POSIX continues: > > With regard to rand(), there are two different behaviors that may be > wanted in a multi-threaded program: > > 1. A single per-process sequence of pseudo-random numbers that is > shared by all threads that call rand() > > 2. A different sequence of pseudo-random numbers for each thread that > calls rand() > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This paragraph continues after the two items: "This is provided by the modified thread-safe function based on whether the seed value is global to the entire process or local to each thread." My understanding of this paragraph is: - If an application wants 1., they can use rand_r with SEED pointing to a global variable. - If an application wants 2., they can use rand_r with SEED pointing to a per-thread variable. > I read this as the newlib technique being one way of correctly > implementing rand/srand, no? I don't think so. The critical sentence is the one with "subsequent calls to rand". Bruno -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple