Correct execution of Final routine in Fortran
I have following Fortran code
type t_octree
integer :: max_num_point
class(t_octree_node), pointer :: root => null()
contains
final :: DESTROY_OCTREE
end type t_octree
type t_octree_node
real :: box(2,3)
integer :: depth
type(t_octree_node), pointer :: parent => null()
type(t_octree_node), pointer :: children(:) => null()
class(t_octree_leaf), pointer :: leaf => null()
contains
final :: CLEAN_NODE
end type t_octree_node
type, extends(t_octree_node) :: t_octree_leaf
integer, allocatable :: id(:)
integer :: num_point
contains
final :: DESTROY_LEAF
end type
After I have done my processing and now need to make sure that my stuff is deallocated properly.
In my `final routines I have
subroutine DESTROY_OCTREE( this )
implicit none
type(t_octree) :: this
type(t_octree_node), pointer :: node => null()
integer :: i
node => this% root
if( associated(node% leaf) )deallocate( node% leaf )
if(.not. associated(node% children) )RETURN
deallocate( node )
node => this% root
i = 0
nullify(node)
print*, associated(this% root) ! this is true!!
print*, associated(this% root% children) ! this is true!!
end subroutine DESTROY_OCTREE
recursive subroutine CLEAN_NODE ( this )
implicit none
type(t_octree_node) :: this
type(t_octree_node), pointer :: node => null(), next => null()
integer :: i
if( associated(this% leaf) )then
deallocate( this% leaf )
nullify( this% leaf )
endif
if(.not. associated(this% children) )RETURN
do i = 1, 8
node => this% children(i)
deallocate( node )
nullify(node)
! debug
! print*, i, "rec"
enddo
nullify(this% children)
nullify(this% parent)
end subroutine CLEAN_NODE
subroutine DESTROY_LEAF ( leaf )
implicit none
type(t_octree_leaf) :: leaf
deallocate( leaf% id )
end subroutine DESTROY_LEAF
In my main program I do following
program TEST_OCTREE
use MD_OCTREE
implicit none
type(t_octree), pointer :: octree
octree => t_octree( max_num_point, box )
(...) ! all processing to build the data structure
Now I deallocate by simply
deallocate( octree )
print*, associated(octree% root) ! this give a segmentation fault
The question
Can somebody explain why it seems that my print*, associated(this% root) commands still show TRUE while when printing in my main program it looks like it has been deallocated as it gives me a segmentation fault
oop fortran intel-fortran finalizer
add a comment |
I have following Fortran code
type t_octree
integer :: max_num_point
class(t_octree_node), pointer :: root => null()
contains
final :: DESTROY_OCTREE
end type t_octree
type t_octree_node
real :: box(2,3)
integer :: depth
type(t_octree_node), pointer :: parent => null()
type(t_octree_node), pointer :: children(:) => null()
class(t_octree_leaf), pointer :: leaf => null()
contains
final :: CLEAN_NODE
end type t_octree_node
type, extends(t_octree_node) :: t_octree_leaf
integer, allocatable :: id(:)
integer :: num_point
contains
final :: DESTROY_LEAF
end type
After I have done my processing and now need to make sure that my stuff is deallocated properly.
In my `final routines I have
subroutine DESTROY_OCTREE( this )
implicit none
type(t_octree) :: this
type(t_octree_node), pointer :: node => null()
integer :: i
node => this% root
if( associated(node% leaf) )deallocate( node% leaf )
if(.not. associated(node% children) )RETURN
deallocate( node )
node => this% root
i = 0
nullify(node)
print*, associated(this% root) ! this is true!!
print*, associated(this% root% children) ! this is true!!
end subroutine DESTROY_OCTREE
recursive subroutine CLEAN_NODE ( this )
implicit none
type(t_octree_node) :: this
type(t_octree_node), pointer :: node => null(), next => null()
integer :: i
if( associated(this% leaf) )then
deallocate( this% leaf )
nullify( this% leaf )
endif
if(.not. associated(this% children) )RETURN
do i = 1, 8
node => this% children(i)
deallocate( node )
nullify(node)
! debug
! print*, i, "rec"
enddo
nullify(this% children)
nullify(this% parent)
end subroutine CLEAN_NODE
subroutine DESTROY_LEAF ( leaf )
implicit none
type(t_octree_leaf) :: leaf
deallocate( leaf% id )
end subroutine DESTROY_LEAF
In my main program I do following
program TEST_OCTREE
use MD_OCTREE
implicit none
type(t_octree), pointer :: octree
octree => t_octree( max_num_point, box )
(...) ! all processing to build the data structure
Now I deallocate by simply
deallocate( octree )
print*, associated(octree% root) ! this give a segmentation fault
The question
Can somebody explain why it seems that my print*, associated(this% root) commands still show TRUE while when printing in my main program it looks like it has been deallocated as it gives me a segmentation fault
oop fortran intel-fortran finalizer
add a comment |
I have following Fortran code
type t_octree
integer :: max_num_point
class(t_octree_node), pointer :: root => null()
contains
final :: DESTROY_OCTREE
end type t_octree
type t_octree_node
real :: box(2,3)
integer :: depth
type(t_octree_node), pointer :: parent => null()
type(t_octree_node), pointer :: children(:) => null()
class(t_octree_leaf), pointer :: leaf => null()
contains
final :: CLEAN_NODE
end type t_octree_node
type, extends(t_octree_node) :: t_octree_leaf
integer, allocatable :: id(:)
integer :: num_point
contains
final :: DESTROY_LEAF
end type
After I have done my processing and now need to make sure that my stuff is deallocated properly.
In my `final routines I have
subroutine DESTROY_OCTREE( this )
implicit none
type(t_octree) :: this
type(t_octree_node), pointer :: node => null()
integer :: i
node => this% root
if( associated(node% leaf) )deallocate( node% leaf )
if(.not. associated(node% children) )RETURN
deallocate( node )
node => this% root
i = 0
nullify(node)
print*, associated(this% root) ! this is true!!
print*, associated(this% root% children) ! this is true!!
end subroutine DESTROY_OCTREE
recursive subroutine CLEAN_NODE ( this )
implicit none
type(t_octree_node) :: this
type(t_octree_node), pointer :: node => null(), next => null()
integer :: i
if( associated(this% leaf) )then
deallocate( this% leaf )
nullify( this% leaf )
endif
if(.not. associated(this% children) )RETURN
do i = 1, 8
node => this% children(i)
deallocate( node )
nullify(node)
! debug
! print*, i, "rec"
enddo
nullify(this% children)
nullify(this% parent)
end subroutine CLEAN_NODE
subroutine DESTROY_LEAF ( leaf )
implicit none
type(t_octree_leaf) :: leaf
deallocate( leaf% id )
end subroutine DESTROY_LEAF
In my main program I do following
program TEST_OCTREE
use MD_OCTREE
implicit none
type(t_octree), pointer :: octree
octree => t_octree( max_num_point, box )
(...) ! all processing to build the data structure
Now I deallocate by simply
deallocate( octree )
print*, associated(octree% root) ! this give a segmentation fault
The question
Can somebody explain why it seems that my print*, associated(this% root) commands still show TRUE while when printing in my main program it looks like it has been deallocated as it gives me a segmentation fault
oop fortran intel-fortran finalizer
I have following Fortran code
type t_octree
integer :: max_num_point
class(t_octree_node), pointer :: root => null()
contains
final :: DESTROY_OCTREE
end type t_octree
type t_octree_node
real :: box(2,3)
integer :: depth
type(t_octree_node), pointer :: parent => null()
type(t_octree_node), pointer :: children(:) => null()
class(t_octree_leaf), pointer :: leaf => null()
contains
final :: CLEAN_NODE
end type t_octree_node
type, extends(t_octree_node) :: t_octree_leaf
integer, allocatable :: id(:)
integer :: num_point
contains
final :: DESTROY_LEAF
end type
After I have done my processing and now need to make sure that my stuff is deallocated properly.
In my `final routines I have
subroutine DESTROY_OCTREE( this )
implicit none
type(t_octree) :: this
type(t_octree_node), pointer :: node => null()
integer :: i
node => this% root
if( associated(node% leaf) )deallocate( node% leaf )
if(.not. associated(node% children) )RETURN
deallocate( node )
node => this% root
i = 0
nullify(node)
print*, associated(this% root) ! this is true!!
print*, associated(this% root% children) ! this is true!!
end subroutine DESTROY_OCTREE
recursive subroutine CLEAN_NODE ( this )
implicit none
type(t_octree_node) :: this
type(t_octree_node), pointer :: node => null(), next => null()
integer :: i
if( associated(this% leaf) )then
deallocate( this% leaf )
nullify( this% leaf )
endif
if(.not. associated(this% children) )RETURN
do i = 1, 8
node => this% children(i)
deallocate( node )
nullify(node)
! debug
! print*, i, "rec"
enddo
nullify(this% children)
nullify(this% parent)
end subroutine CLEAN_NODE
subroutine DESTROY_LEAF ( leaf )
implicit none
type(t_octree_leaf) :: leaf
deallocate( leaf% id )
end subroutine DESTROY_LEAF
In my main program I do following
program TEST_OCTREE
use MD_OCTREE
implicit none
type(t_octree), pointer :: octree
octree => t_octree( max_num_point, box )
(...) ! all processing to build the data structure
Now I deallocate by simply
deallocate( octree )
print*, associated(octree% root) ! this give a segmentation fault
The question
Can somebody explain why it seems that my print*, associated(this% root) commands still show TRUE while when printing in my main program it looks like it has been deallocated as it gives me a segmentation fault
oop fortran intel-fortran finalizer
oop fortran intel-fortran finalizer
edited Dec 27 '18 at 22:09
asked Dec 27 '18 at 21:48
A2LBK
776
776
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.
The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.
When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.
There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to myoctree => t_octree( max_num_point, box )whereoctreeis a pointer. ? If yes then this is what my problem is: I did before just dooctree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction,final, was executed. When having a pointer I can control when thefinalis invoked by just having the explicit DEALLOCATE statement
– A2LBK
Dec 28 '18 at 21:56
So when I didoctree=t_octree( max_num_point, box ), thefinalroutine was also executed, while it did not execute before the program exited
– A2LBK
Dec 28 '18 at 21:59
|
show 7 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53951210%2fcorrect-execution-of-final-routine-in-fortran%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.
The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.
When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.
There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to myoctree => t_octree( max_num_point, box )whereoctreeis a pointer. ? If yes then this is what my problem is: I did before just dooctree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction,final, was executed. When having a pointer I can control when thefinalis invoked by just having the explicit DEALLOCATE statement
– A2LBK
Dec 28 '18 at 21:56
So when I didoctree=t_octree( max_num_point, box ), thefinalroutine was also executed, while it did not execute before the program exited
– A2LBK
Dec 28 '18 at 21:59
|
show 7 more comments
Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.
The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.
When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.
There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to myoctree => t_octree( max_num_point, box )whereoctreeis a pointer. ? If yes then this is what my problem is: I did before just dooctree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction,final, was executed. When having a pointer I can control when thefinalis invoked by just having the explicit DEALLOCATE statement
– A2LBK
Dec 28 '18 at 21:56
So when I didoctree=t_octree( max_num_point, box ), thefinalroutine was also executed, while it did not execute before the program exited
– A2LBK
Dec 28 '18 at 21:59
|
show 7 more comments
Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.
The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.
When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.
There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.
Deallocating a pointer causes the pointer association status of any other pointer that was associated with the same target to become undefined (F2018 9.7.3.3p2). This situation happens with node and this%root in the DESTROY_OCTREE procedure - both pointers reference the same object (via the pointer assignment node => this% root, the object is deallocated through the node pointer - which makes this%root have undefined association status.
The argument to the ASSOCIATED intrinsic must not be a pointer with undefined association status (F2018 16.9.16p3). The code is non-conforming, anything may happen - where "anything" quite reasonably includes the results you see.
When you deallocate the object through the node pointer, there is no simple way that the processor can also reliably update the status of the this%root pointer - it ends up pointing at something that no longer exists.
There are other suspicious constructs in the fragments of source shown, including use of a superfluous NULLIFY after a DEALLOCATE statement on the same pointer object (successful deallocation disassociates (nullifies) the pointer), use of nullify when perhaps DEALLOCATE is appropriate (hard to say without complete code), and use of what appears to be a structure constructor as a pointer target.
answered Dec 27 '18 at 22:48
IanH
17.2k22244
17.2k22244
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to myoctree => t_octree( max_num_point, box )whereoctreeis a pointer. ? If yes then this is what my problem is: I did before just dooctree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction,final, was executed. When having a pointer I can control when thefinalis invoked by just having the explicit DEALLOCATE statement
– A2LBK
Dec 28 '18 at 21:56
So when I didoctree=t_octree( max_num_point, box ), thefinalroutine was also executed, while it did not execute before the program exited
– A2LBK
Dec 28 '18 at 21:59
|
show 7 more comments
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to myoctree => t_octree( max_num_point, box )whereoctreeis a pointer. ? If yes then this is what my problem is: I did before just dooctree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction,final, was executed. When having a pointer I can control when thefinalis invoked by just having the explicit DEALLOCATE statement
– A2LBK
Dec 28 '18 at 21:56
So when I didoctree=t_octree( max_num_point, box ), thefinalroutine was also executed, while it did not execute before the program exited
– A2LBK
Dec 28 '18 at 21:59
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Thanks for the answer. In other words my destructor has essentially deallocated my tree structure. I see what you mean regarding NULLIFY after DEALLOCATE statements. What else is suspicious?
– A2LBK
Dec 28 '18 at 9:23
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
Also, what do you mean by the code is non-conforming?
– A2LBK
Dec 28 '18 at 9:30
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
The OP created constructors as pointer functions with allocations. I tried to atress it is a bad practice, but the usage of the constructor as a pointer target is probably connected to that.
– Vladimir F
Dec 28 '18 at 10:25
@VladimirF, Are you referring to my
octree => t_octree( max_num_point, box )where octree is a pointer. ? If yes then this is what my problem is: I did before just do octree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction, final, was executed. When having a pointer I can control when the final is invoked by just having the explicit DEALLOCATE statement– A2LBK
Dec 28 '18 at 21:56
@VladimirF, Are you referring to my
octree => t_octree( max_num_point, box )where octree is a pointer. ? If yes then this is what my problem is: I did before just do octree=t_octree( max_num_point, box ), but then as soon as the construction was finished, the destruction, final, was executed. When having a pointer I can control when the final is invoked by just having the explicit DEALLOCATE statement– A2LBK
Dec 28 '18 at 21:56
So when I did
octree=t_octree( max_num_point, box ), the final routine was also executed, while it did not execute before the program exited– A2LBK
Dec 28 '18 at 21:59
So when I did
octree=t_octree( max_num_point, box ), the final routine was also executed, while it did not execute before the program exited– A2LBK
Dec 28 '18 at 21:59
|
show 7 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53951210%2fcorrect-execution-of-final-routine-in-fortran%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown