I'm trying to get quad precision to work with my FORTRAN code. I have to replace some intrinsic functions by those in libquadmath, i.e. the dabs function by fabsq.
Unfortunately, if I compile the following test function
program test
integer dp
parameter (dp=10)
real(kind=dp) a
a= -5.0_dp
a=fabsq(a)
write(*,*) "abs(a)", a
end program
I obtain some error at compile time
gfortran -lquadmath -o test.out test.f
/tmp/ccwhLFWr.o: In function `MAIN__':
test.f:(.text+0x2e): undefined reference to `fabsq_'
collect2: error: ld returned 1 exit status
but
nm /usr/lib64/gcc/x86_64-suse-linux/4.8/libquadmath.a | grep -c fabsq
gives me some value greater than 0. What's going wrong here?
In general, things like "dabs" were from the days before type-generic intrinsics. In particular, there is no corresponding "qabs/absq" or whatever you might want to call it, but rather only the type-generic "abs" which is then resolved to the correct library symbol at compile time.
Secondly, your choice of "abs" to test with is a bit unfortunate, since it turns out the compiler expands that inline so you'll never see any function calls. A better choice is e.g. "sin". Consider the example code
Compiling this with "gfortran -c -O2 -S qm.f90", and inspecting the generated code one sees:
So one sees that the call to "abs" is handled by inline code, no need to call some external function. OTOH, the call to the generic "sin()" function is resolved to the "sinq" function, which is a quad precision version of the sine function that you can find in libquadmath. No need to try to call "sinq" explicitly, in fact it wouldn't work.
Note also the usage of "real(16)", which is unportable, but a quick-and-dirty way of getting quad precision reals in gfortran.
PS: Another thing, with gfortran there is no need to explicitly link with libquadmath, it's automatically included, just like libgfortran, libm, etc.