Mike, 

No. I hacked the Quad_RVAL.cc so that the code that would have compiled on Linux (where configure would set HAVE_LIBC by finding initstate_r() ) would be compiled - which it does. And seems to run in cursory testing. 

My point is that the code does not behave as advertised and may be limiting platforms from running  ⎕RVAL that could. The code is using the “standard” versions (initstate, setstate, and random) of those functions instead of the _r versions.

Hence my question to Jürgen.  

- Paul 

Sent from my iPad

On Dec 2, 2025, at 4:49 PM, M.Hall <[email protected]> wrote:


This was from me complaining to Jurgen in January 2025 that macos didn't have quad-rval because it doesn't have glibc and initstate_r  -- even though it *does* have 'initstate'.  The changes were around svn 1820.

So your macos finds initstate_r and friends?

On Tue, Dec 2, 2025 at 3:32 PM Paul Rockwell <[email protected]> wrote:
In src/Quad_RVAL.cc and the GNU APL info doc, it's stated that the ⎕RVAL operator requires glibc. This is stated to be required due to the use of the glibc functions random_r(),  which would also imply the use of initstate_r() and setstate_r() to initialize and set the state. 

However, looking at the source, there is no use of these glibc functions. The code uses random(), initstate(), and setstate() -- which are available on platforms that use libraries other than glibc (for example macOS).

//----------------------------------------------------------------------------
Quad_RVAL::Quad_RVAL()
   : QuadFunction(TOK_Quad_RVAL)
{
enum { count = sizeof(subfunction_infos) / sizeof(*subfunction_infos) };
   init_function_group(subfunction_infos, count, "⎕RVAL");

   N = 8;
   desired_maxdepth = 4;
   memset(state, 0, sizeof(state));
   initstate(1, state, N);                    // <<< uses initstate() instead of initstate_r()

   while (desired_shape.get_rank() < MAX_RANK)
         desired_shape.add_shape_item(1);

   desired_ranks.push_back(0);

   desired_types.push_back(0);   // no chars
   desired_types.push_back(1);   // ints
   desired_types.push_back(0);   // no real
   desired_types.push_back(0);   // no complex
   desired_types.push_back(0);   // no nested
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
Value_P
Quad_RVAL::generator_state(const Value & B)
{
   // expect an empty, 8, 16, 32, 64, 128, or 256 byte integer vector
   //
   if (B.get_rank() != 1)   RANK_ERROR;

const ShapeItem new_N = B.element_count();
   if (new_N !=   0 && new_N !=   8 && new_N !=  32 &&
       new_N !=  64 && new_N != 128 && new_N != 256)
      {
        MORE_ERROR() << "bad new_N (aka. ⍴B) in generator_state()";
        LENGTH_ERROR;
      }

   // always return the previous state
   //
Value_P Z(N, LOC);
   loop(n, N)   Z->next_ravel_Int(state[n] & 0xFF);
   Z->check_value(LOC);

   if (new_N)   // set generator state
      {
        // make sure that all values are bytes
        //
        loop(b, N)
            {
              const APL_Integer byte = B.get_cravel(b).get_int_value();
              if ((byte < -256) || (byte >  255))
                 {
                   MORE_ERROR() << "Bad right argument B in 0 ⎕RVAL B,"
                                   "expecting bytes (integers -256...255)";
                   DOMAIN_ERROR;
                 }
            }
        N = new_N;
        loop(b, N)
            {
               state[b] = B.get_cravel(b).get_int_value();
            }
         setstate(state);     // uses setstate() instead of setstate_r()
      }

   return Z;
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
uint64_t
Quad_RVAL::rand17()
{
const int32_t rnd = random();     // uses random() instead of random_r()

   // the lower bits are less random, so we xor the upper 16 bits into
   // the lower 16 bits and return them.
   return (rnd ^ (rnd >> 16)) & 0x1FFFF;
}
//----------------------------------------------------------------------------

I have tested a build of GNU APL SVN 1922 and "reversed" the test for the HAVE_LIBC in Quadf_RVAL.cc so that the code would try to be compiled under macOS. Everything related to ⎕RVAL seems to work in my limited testing (it at least didn't crash the interpreter).

Is the use of random() instead of random_r(), etc. in the code an oversight. Or is the documentation incorrect?

- Paul Rockwell




--
Mike Hall


Reply via email to