추상 유형으로 지원되는 다형성을 사용하여 수치 최적화를위한 객체 지향 포트란 코드를 개발 중입니다. 좋은 TDD 연습이므로 추상화 유형 class(generic_optimizer)
에 모든 최적화 테스트를 작성하려고합니다. 그러면 각 인스턴스화 된 클래스에 의해 실행되어야합니다 (예 : type(newton_raphson)
).지연 함수 및 non_overridable 키워드로 세그먼트 오류
모든 최적화 테스트에는 call my_problem%solve(...)
에 대한 호출이 있으며, 이는 추상 유형으로 deferred
으로 정의되며 물론 각 파생 유형에서 다른 구현을 특징으로합니다.
문제는 다음 몇 가지 시행 착오 후
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
로 이연 함수를 정의하면, 내가 같은 세그먼트 오류를 얻을 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
Deferreds와 어떤 관련이 있습니까? –