- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following code, when compiled with ifort, calls the final subroutine of the `test_type` object twice just to construct the object. GNU Fortran compiler (does not call the final routine at all apparently).
module test_mod
type :: test_type
integer :: unit = -huge(0)
contains
final :: finalize
end type
interface test_type
module procedure :: constructTest
end interface
contains
function constructTest(file) result(test)
character(*), intent(in) :: file
type(test_type) :: test
open(newunit = test%unit, file = file)
end
subroutine finalize(test)
type(test_type), intent(inout) :: test
logical :: opened
print *, "this final subroutine should not be called!"
inquire(unit = test%unit, opened = opened)
if (opened) close(test%unit)
end
end module
use test_mod
logical :: opened
type(test_type) :: test
test = test_type("test.txt")
inquire(unit = test%unit, opened = opened)
print *, opened
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suspect that line 35 creates a temporary test_type object on the stack for use in the copy operation to the local variable test, then the destruction of the stack object calls the final which closes the unit as indicated in both the stack copy and the lhs copy, but leaves the state variable opened in the lhs alone.. What you may need to do (though it may or may not meet your requirements) is to create a copy operator(=) that sets the rhs opened to .false. (after the copy).
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suspect that line 35 creates a temporary test_type object on the stack for use in the copy operation to the local variable test, then the destruction of the stack object calls the final which closes the unit as indicated in both the stack copy and the lhs copy, but leaves the state variable opened in the lhs alone.. What you may need to do (though it may or may not meet your requirements) is to create a copy operator(=) that sets the rhs opened to .false. (after the copy).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel Fortran behavior is indeed as stated in the standard where in an intrinsic assignment, a finalizable object on the LHS gets finalized before being defined using the function result and the object(s) corresponding to the evaluation of the expr on RHS get finalized also.
As alluded to by @jimdempseyatthecove , you need a different approach:
- consider using some setter method(s) toward initialization of your derived type with suitable actions (such as resource allocations, etc. including file connections) and
- avoid so-called "constructors" i.e., the use of a generic interface with the same name as the derived type to functions that imitate object construction - you will find they are more trouble than they are worth.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Defined assignment can help here - as the copy semantics of intrinsic assignment don't match your requirements. You probably want move semantics.
If you have a type in Fortran that is representing an resource of some sort (in your case a file), you pretty much always need defined assignment. Often that implies that if you have a type with a finalizer (which is there to manage the cleanup of a resource), you need defined assignment.
(Defined assignment can hinder in other ways, or bring other requirements with it.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all. I agree that a defined assignment is the ultimate clean solution. For now, I managed to get the problem solved by adding an internal private flag to the type that keeps track of the calls made to the constructor.
The forum does not allow me to edit the title of this page, which now appears to be incorrect (this is not an ifort bug).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page