From: Keith.S.Thompson+u@gmail.com   
      
   Michael Sanders writes:   
   > On Wed, 07 Jan 2026 13:54:21 -0800, Keith Thompson wrote:   
   >> Tim Rentsch writes:   
   [...]   
   >>> Apples and oranges. Many applications that use random numbers   
   >>> need a stream of numbers that is deterministic and reproducible,   
   >>> which /dev/urandom is not.   
   >>   
   >> And neither is the non-conforming rand() on OpenBSD.   
   >>   
   >> The rand(1) man page on OpenBSD 7.8 says:   
   >>   
   >> Standards insist that this interface return deterministic   
   >> results. Unsafe usage is very common, so OpenBSD changed the   
   >> subsystem to return non-deterministic results by default.   
   >>   
   >> To satisfy portable code, srand() may be called to initialize   
   >> the subsystem. In OpenBSD the seed variable is ignored,   
   >> and strong random number results will be provided from   
   >> arc4random(3). In other systems, the seed variable primes a   
   >> simplistic deterministic algorithm.   
   >>   
   >> It does provide an srand_deterministic() function that behaves the way   
   >> srand() is supposed to.   
   >   
   > So then clang would use:   
   >   
   > #ifdef __OpenBSD__   
   > srand_deterministic(seed);   
   > #else   
   > srand(seed);   
   > #endif   
   >   
   > But I don't know (yet) that gcc does as well under OpenBSD.   
      
   I don't know what you mean when you say that clang "would use"   
   that code.   
      
   I'm not aware that either clang or gcc uses random numbers   
   internally. I don't know why they would.   
      
   You could certainly write the above code and compile it with either   
   gcc or clang (or any other C compiler on OpenBSD). I've confirmed   
   that gcc on OpenBSD does predefine the symbol __OpenBSD__. There   
   should be no relevant difference between gcc and clang; random   
   number generation is implemented in the library, not in the compiler.   
      
   If your point is that a programmer using either gcc or clang could   
   use the above code to get the required deterministic behavior   
   for rand(), I agree. (Though it shouldn't be necessary; IMHO the   
   OpenBSD folks made a very bad decision.)   
      
   Relatedly, the NetBSD implementation of rand() is conforming, but   
   of very low quality. The low-order bit alternates between 0 and   
   1 on successive rand() calls, the two low-order bits repeat with   
   a cycle of 4, and so on. Larry Jones wrote about it here in 2010:   
      
    The even/odd problem was caused at Berkeley by a well meaning   
    but clueless individual who increased the range of the generator   
    (which originally matched the sample implementation) by returning   
    the *entire* internal state rather than just the high-order   
    bits of it. BSD was very popular, so that defective generator   
    got around a lot, unfortunately.   
      
   And I've just discovered that the OpenBSD rand() returns alternating   
   odd and even results after a call to srand_determinstic().   
      
   It's disturbing that this has never been fixed.   
      
   --   
   Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com   
   void Void(void) { Void(); } /* The recursive call of the void */   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|