Silverfrost Forums

Welcome to our forums

SCC /64 refuses to compile C source file

10 Sep 2020 2:00 #26333

The C routine given below implements Marsaglia's KISS RNG. The C code uses unsigned integer arithmetic, so it is not easy to convert to Fortran.

SCC compiles it with no problems, except when /64 is used, in which case it issues a load of spurious error messages.

/* SUPRKISS32.c, period 5*2^1320481*(2^32-1) */
#ifdef LF
#define RANDOM_R8 random_r8_
#define INITKISS32 initkiss32_
#endif
#define BSIZE 41265
static unsigned long Q[BSIZE],indx=BSIZE,
   carry=362,xcng=1236789,xs=521288629;

#define CNG ( xcng=69609*xcng+123 ) /*Congruential*/
#define XS ( xs^=xs<<13,xs^=xs>>17,xs^=xs>>5 )/*Xorshift*/
#define SUPR ( indx<BSIZE ? Q[indx++] : refill() ) /*CMWC*/
#define KISS SUPR+CNG+XS

int refill( )
{int i; unsigned long z,h;
for(i=0;i<BSIZE;i++){ 
   h=(carry&1);
   z=((Q[i]<<9)>>1)+((Q[i]<<7)>>1)+(carry>>1);
   carry=(Q[i]>>23)+(Q[i]>>25)+(z>>31);
   Q[i]=~((z<<1)+h); 
   }
indx=1; return (Q[0]);
}

#ifdef FTN95
extern 'C' 
#endif
   void RANDOM_R8(double *x, int *n){
   int i;
   for (i=0; i<*n; i++)x[i] = (KISS)/4294967296.0;
   }
#ifdef FTN95
extern 'C'
#endif
void INITKISS32( ){
   unsigned long i;
   for(i=0;i<BSIZE;i++) Q[i]=CNG+XS;
   indx = 0;
   }

I have sometimes wondered why SCC insists on treating C code as if it were C++ code, and decorates routine names a la C++, forcing the user to add extern 'C' to enable using the resulting OBJ with Fortran routines. When building 32-bit code, we can use another C compiler.

When building 64-bit code, there is no other C compiler that produces OBJs that slink64 can work with, so bugs in SCC /64 pose an insurmountable obstacle.

10 Sep 2020 6:29 #26334

mecej4

We will take a look at this. The alternative may be to put the C code into a third party DLL.

10 Sep 2020 7:11 #26336

Thanks, Paul. I already use that solution (building a DLL using a third-party compiler and linking FTN95 code with the DLL), but in this case there is a major inconvenience associated with doing so.

The Marsaglia algorithm employs a large static unsigned int Q[] array and other scalar variables, the contents of which (i.e., the state of the RNG) would need to be preserved between calls to the routine in the DLL. The MS linker provides ways to share data between a DLL and the caller, but does SLINK64 do so?

The alternative would be to move the static variables into the argument list of the DLL routine, but that also has disadvantages. The user would need to make sure to know the list of variables used in the DLL routine, as well as to declare and initialise them as necessary in the Fortran caller.

10 Sep 2020 9:15 #26337

SLINK64 does not provide a way to share data.

I will get back to you when I have the report.

Please login to reply.