gfortran 在 libquadmath 中找不到符号 fabsq_
gfortran does not find symbol fabsq_ in libquadmath
我正在尝试获得四精度来处理我的 FORTRAN 代码。我必须用 libquadmath 中的函数替换一些内部函数,即 fabsq 的 dabs 函数。
不幸的是,如果我编译下面的测试函数
program test
integer dp
parameter (dp=10)
real(kind=dp) a
a= -5.0_dp
a=fabsq(a)
write(*,*) "abs(a)", a
end program
编译时出现一些错误
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
但是
nm /usr/lib64/gcc/x86_64-suse-linux/4.8/libquadmath.a | grep -c fabsq
给我一些大于 0 的值。这里出了什么问题?
尝试gfortran -o test.out test.f -lquadmath
。
一般来说,像 "dabs" 这样的东西是在类型泛型内在函数出现之前的。特别是,没有相应的 "qabs/absq" 或任何您可能想要调用它的东西,而只有类型泛型 "abs",然后在编译时解析为正确的库符号。
其次,您选择 "abs" 进行测试有点不幸,因为事实证明编译器会扩展该内联,因此您永远不会看到任何函数调用。更好的选择是例如"sin"。考虑示例代码
function my_sintest(a)
real(16) :: a, my_sintest
my_sintest = sin(a)
end function my_sintest
function my_abstest(a)
real(16) :: a, my_abstest
my_abstest = abs(a)
end function my_abstest
用 "gfortran -c -O2 -S qm.f90" 编译它,并检查生成的代码可以看到:
.file "qm.f90"
.text
.p2align 4,,15
.globl my_sintest_
.type my_sintest_, @function
my_sintest_:
.LFB0:
.cfi_startproc
movdqa (%rdi), %xmm0
jmp sinq
.cfi_endproc
.LFE0:
.size my_sintest_, .-my_sintest_
.p2align 4,,15
.globl my_abstest_
.type my_abstest_, @function
my_abstest_:
.LFB1:
.cfi_startproc
movdqa (%rdi), %xmm0
pand .LC0(%rip), %xmm0
ret
.cfi_endproc
.LFE1:
.size my_abstest_, .-my_abstest_
.section .rodata.cst16,"aM",@progbits,16
.align 16
.LC0:
.long 4294967295
.long 4294967295
.long 4294967295
.long 2147483647
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
所以可以看出对"abs"的调用是由内联代码处理的,不需要调用一些外部函数。 OTOH,对通用 "sin()" 函数的调用被解析为 "sinq" 函数,它是正弦函数的四精度版本,您可以在 libquadmath 中找到它。无需尝试显式调用 "sinq",实际上它不会起作用。
另请注意 "real(16)" 的用法,它不可移植,但却是在 gfortran 中获取四精度实数的一种快速而肮脏的方法。
PS:另一件事,对于 gfortran,无需显式 link 与 libquadmath,它会自动包含,就像 libgfortran、libm 等
我正在尝试获得四精度来处理我的 FORTRAN 代码。我必须用 libquadmath 中的函数替换一些内部函数,即 fabsq 的 dabs 函数。
不幸的是,如果我编译下面的测试函数
program test
integer dp
parameter (dp=10)
real(kind=dp) a
a= -5.0_dp
a=fabsq(a)
write(*,*) "abs(a)", a
end program
编译时出现一些错误
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
但是
nm /usr/lib64/gcc/x86_64-suse-linux/4.8/libquadmath.a | grep -c fabsq
给我一些大于 0 的值。这里出了什么问题?
尝试gfortran -o test.out test.f -lquadmath
。
一般来说,像 "dabs" 这样的东西是在类型泛型内在函数出现之前的。特别是,没有相应的 "qabs/absq" 或任何您可能想要调用它的东西,而只有类型泛型 "abs",然后在编译时解析为正确的库符号。
其次,您选择 "abs" 进行测试有点不幸,因为事实证明编译器会扩展该内联,因此您永远不会看到任何函数调用。更好的选择是例如"sin"。考虑示例代码
function my_sintest(a)
real(16) :: a, my_sintest
my_sintest = sin(a)
end function my_sintest
function my_abstest(a)
real(16) :: a, my_abstest
my_abstest = abs(a)
end function my_abstest
用 "gfortran -c -O2 -S qm.f90" 编译它,并检查生成的代码可以看到:
.file "qm.f90"
.text
.p2align 4,,15
.globl my_sintest_
.type my_sintest_, @function
my_sintest_:
.LFB0:
.cfi_startproc
movdqa (%rdi), %xmm0
jmp sinq
.cfi_endproc
.LFE0:
.size my_sintest_, .-my_sintest_
.p2align 4,,15
.globl my_abstest_
.type my_abstest_, @function
my_abstest_:
.LFB1:
.cfi_startproc
movdqa (%rdi), %xmm0
pand .LC0(%rip), %xmm0
ret
.cfi_endproc
.LFE1:
.size my_abstest_, .-my_abstest_
.section .rodata.cst16,"aM",@progbits,16
.align 16
.LC0:
.long 4294967295
.long 4294967295
.long 4294967295
.long 2147483647
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
所以可以看出对"abs"的调用是由内联代码处理的,不需要调用一些外部函数。 OTOH,对通用 "sin()" 函数的调用被解析为 "sinq" 函数,它是正弦函数的四精度版本,您可以在 libquadmath 中找到它。无需尝试显式调用 "sinq",实际上它不会起作用。
另请注意 "real(16)" 的用法,它不可移植,但却是在 gfortran 中获取四精度实数的一种快速而肮脏的方法。
PS:另一件事,对于 gfortran,无需显式 link 与 libquadmath,它会自动包含,就像 libgfortran、libm 等