About five years ago, I had noticed and reported ( https://forums.silverfrost.com/Forum/Topic/3293 ) the presence of the Netlib/PORT/SLATEC/BLAS/LAPACK routines D1MACH() and I1MACH() in the FTN95 RTL DLLs SALFLIBC.DLL and SALFLIBC64.DLL. These are undocumented, but appear to have the same functionality as the Netlib routines of the same name. They are not accurate, however, as this test program illustrates.
program tmach
integer i,i1mach
double precision d1mach
integer*8 i8
!
print *,' i D1MACH(i) Expected'
print *
print 10,1,transfer(d1mach(1),i8), transfer(tiny(1.0d0),i8)
print 10,2,transfer(d1mach(2),i8), transfer(huge(1.0d0),i8)
print 10,3,transfer(d1mach(3),i8), transfer(epsilon(1.0d0)/2,i8)
print 10,4,transfer(d1mach(4),i8), transfer(epsilon(1.0d0),i8)
10 format(1x,i2,4x,2Z20.16)
end program
The output from the program (32-bit or 64-bit):
i D1MACH(i) Expected
1 0010000005017817 0010000000000000
2 7FEFFFFFF596AC44 7FEFFFFFFFFFFFFF
3 3C9FFFFFF4178DA3 3CA0000000000000
4 3CAFFFFFF4178DA3 3CB0000000000000
Today, while attempting to build a SLATEC DLL using FTN95, I ran into a more serious problem. SLATEC makes heavy use of an error reporting routine called XERMSG, which has the following signature:
subroutine xermsg(Librar,Subrou,Messg,Nerr,Level)
The first three arguments are strings, and the last two are integers. It so happens, quite unexpectedly, that SALFLIBC/SALFLIC64 contain their own XERMSG, with a different signature. If the user is not aware of this, or is not able to control the order in which the linker searches for external routines, an EXE built with FTN95 may contain the FTN95 version instead of the Netlib version.
The following program demonstrates the problem.
program driver
integer ndeg,ierr
real coeff(2), root(1)
ndeg = 0
coeff(1) = 1.0
coeff(2) = 2.0
call rpqr79(ndeg,coeff,root,ierr)
end program
subroutine rpqr79(Ndeg,Coeff,Root,Ierr)
!
!
integer Ierr, Ndeg
real Coeff(*), Root(*)
!
! real scale
Ierr = 0
if ( abs(Coeff(1)) == 0.0 ) then
Ierr = 2
call xermsg('SLATEC','RPQR79','LEADING COEFFICIENT IS ZERO.',2,1)
return
end if
!
if ( Ndeg <= 0 ) then
Ierr = 3
call xermsg('SLATEC','RPQR79','DEGREE INVALID.',3,1)
return
end if
!
if ( Ndeg == 1 ) then
Root(1) = -Coeff(2)/Coeff(1)
return
end if
end subroutine rpqr79
If you forget to link in the dozens of SLATEC routines that report errors, the program uses the routine in the compiler RTL DLLs, and the result is a crash:
Invalid argument to numeric intrinsic function at address 1a0094dd
Within file rpqr79.exe
in RPQR79 in line 27, at address 195
in DRIVER in line 8, at address 69