我正在開發一個面向對象的Fortran代碼,用於抽象類型支持的多態性的數值優化。由於這是一個很好的TDD實踐,我試圖編寫抽象類型爲class(generic_optimizer)
的所有優化測試,然後應該由每個實例化的類運行,例如type(newton_raphson)
。帶延遲函數和非可重複關鍵字的分段錯誤
所有的優化測試都會調用call my_problem%solve(...)
,在抽象類型中定義爲deferred
,當然在每個派生類型中都有不同的實現。
的問題是:如果每個非抽象類我定義的延遲功能non_overridable
,我得到分段錯誤,如:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ??()
(gdb) where
#0 0x0000000000000000 in ??()
#1 0x0000000000913efe in __newton_raphson_MOD_nr_solve()
#2 0x00000000008cfafa in MAIN__()
#3 0x00000000008cfb2b in main()
#4 0x0000003a3c81ed5d in __libc_start_main() from /lib64/libc.so.6
#5 0x00000000004048f9 in _start()
經過一些試驗和錯誤,我注意到,如果我刪除non_overridable
聲明,我可以避免該錯誤。在這種情況下,這不是問題,但我想強制執行,因爲此代碼不可能有兩種多態性。我違反了標準的任何要求嗎?
以下是重現錯誤的示例代碼。我一直在用gfortran 5.3.0和6.1.0進行測試。
module generic_type_module
implicit none
private
type, abstract, public :: generic_type
real(8) :: some_data
contains
procedure (sqrt_interface), deferred :: square_root
procedure, non_overridable :: sqrt_test
end type generic_type
abstract interface
real(8) function sqrt_interface(this,x) result(sqrtx)
import generic_type
class(generic_type), intent(in) :: this
real(8), intent(in) :: x
end function sqrt_interface
end interface
contains
subroutine sqrt_test(this,x)
class(generic_type), intent(in) :: this
real(8), intent(in) :: x
print *, 'sqrt(',x,') = ',this%square_root(x)
end subroutine sqrt_test
end module generic_type_module
module actual_types_module
use generic_type_module
implicit none
private
type, public, extends(generic_type) :: crashing
real(8) :: other_data
contains
procedure, non_overridable :: square_root => crashing_square_root
end type crashing
type, public, extends(generic_type) :: working
real(8) :: other_data
contains
procedure :: square_root => working_square_root
end type working
contains
real(8) function crashing_square_root(this,x) result(sqrtx)
class(crashing), intent(in) :: this
real(8), intent(in) :: x
sqrtx = sqrt(x)
end function crashing_square_root
real(8) function working_square_root(this,x) result(sqrtx)
class(working), intent(in) :: this
real(8), intent(in) :: x
sqrtx = sqrt(x)
end function working_square_root
end module actual_types_module
program deferred_test
use actual_types_module
implicit none
type(crashing) :: crashes
type(working) :: works
call works%sqrt_test(2.0_8)
call crashes%sqrt_test(2.0_8)
end program
從簡單的看,沒有明顯的原因爲什麼'non_overridable'屬性被禁止(並且以後不會嘗試覆蓋)。不過,我無法訪問編譯器來重現此問題。 – francescalus
對我來說看起來像一個編譯器錯誤。 – IanH
這與延遲有什麼關係? –