- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I have a couple of questions:
When I try to compile the code below, I get the an error related to the declaration of b. Is the diagnostic correct? LEN_TRIM is an elemental function, so there shouldn't be a problem with that.
!---------------------------------------------------------------------------------------------------
module mod1
implicit none
type :: whatever
character(:), allocatable :: a
end type
contains
subroutine sub1(arg)
type(whatever), intent(IN) :: arg(:)
integer :: i
character(LEN = MAXVAL([(LEN_TRIM(arg(i)%a), i = 1, SIZE(arg))])) :: a
! character(LEN = MAXVAL(LEN_TRIM(arg%a))) :: b
end subroutine
end module mod1
!---------------------------------------------------------------------------------------------------
Also, I am getting an error related to the PROTECTED attribute (in the code below). I don't know much about interpretation of the standard, but I checked and the "variable definition context" restriction doesn't mention the FILE specifier in the OPEN statement ---it seems to me that the compiler is taking it as an INQUIRE statement.
!---------------------------------------------------------------------------------------------------
module mod1
implicit none
character(5), protected :: filename = 'afile'
end module mod1
module mod2
use mod1
implicit none
contains
subroutine readSomething()
continue
open (unit = 12345, file = filename, status = 'unknown', action = 'read')
close (12345)
end subroutine
end module mod2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
character(:), allocatable :: array(:)
Here's my take - in the above, you've got one data object ("array"), which is of a single, specific type. That specific type has a single type name (CHARACTER) and also a single set of type parameters, which includes a single LEN type parameter represented by the first (:). It happens to be a deferred length type parameter, so it can change at run time, but there's still only one value for that LEN type parameter at an instant in time for that particular data object.
That object happens to be an array. Each element in that array has the same type as the array itself, so all elements have the same LEN type parameter at an instant in time in program execution.
For arrays of strings with lengths that vary within the array, consider something along the lines of:
TYPE string_wrapper
CHARACTER(:), ALLOCATABLE :: contents
END TYPE string_wrapper
TYPE(string_wrapper), ALLOCATABLE :: array(:)
ALLOCATE(array(4))
array(1)%contents = 'iso_varying_string'
array(2)%contents = 'still'
array(3)%contents = 'lives!'
array(4)%contents = '(sort of...)'
If you wanted to, with a bit of data hiding, some appropriate structure constructors, user defined operators and assignment, a few "forwarding" procedures as equivalents for the various intrinsics and a dash of user defined type io (when supported) you'd get something similar to what you were originally expecting in a relatively seamless way, including (if you really wanted) an elemental equivalent of TRIM.
What I'm describing is essentially an updated implementation of varying_string from iso_varying_string, that wraps a scalar deferred length character component rather than the customary array of single characters and, as a result, could be much more "natural". Someone may have already done it.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ups, sorry. I forgot to remove the comment in the line that causes the error. I should be:
!---------------------------------------------------------------------------------------------------
module mod1
implicit none
type :: whatever
character(:), allocatable :: a
end type
contains
subroutine sub1(arg)
type(whatever), intent(IN) :: arg(:)
integer :: i
character(LEN = MAXVAL([(LEN_TRIM(arg(i)%a), i = 1, SIZE(arg))])) :: a
character(LEN = MAXVAL(LEN_TRIM(arg%a))) :: b
end subroutine
end module mod1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try
character(LEN = MAXVAL(LEN_TRIM(arg(:)%a))) :: b
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try
character(LEN = MAXVAL(LEN_TRIM(arg(:)%a))) :: b
Jim Dempsey
Using a slice, instead of the whole array, doesn't make any difference ---besides, I don't need a workaround (since my sample code already includes one, when declaring a); just a confirmation that the error thrown by the compiler is wrong... Or that the code is invalid and the compiler is free to do whatever it wants.
But thanks anyway for the "tip".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's fine... And regarding weird constraints in the standard, I have an additional question: I've found that if I declare an allocatable array of deferred length characters, the length of every component remains fixed, as in:
!----
character(:), allocatable :: array(:)
allocate (array(5), source = '')
do i = 1, 5
array(i) = 'something'
print *, array(i) !nothing is printed, since length is still zero
enddo
end
!----
It wouldn't surprise me if it's something required by the standard, just like (I suppose, the reason of) TRIM not being elemental, because the resulting arrays would have elements with different lengths. I vaguely remember having read a rule stating that array elements cannot have the allocatable attribute. But, is it true also in this case, or is it just a bug in the current version of the compiler?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
character(:), allocatable :: array(:)
Here's my take - in the above, you've got one data object ("array"), which is of a single, specific type. That specific type has a single type name (CHARACTER) and also a single set of type parameters, which includes a single LEN type parameter represented by the first (:). It happens to be a deferred length type parameter, so it can change at run time, but there's still only one value for that LEN type parameter at an instant in time for that particular data object.
That object happens to be an array. Each element in that array has the same type as the array itself, so all elements have the same LEN type parameter at an instant in time in program execution.
For arrays of strings with lengths that vary within the array, consider something along the lines of:
TYPE string_wrapper
CHARACTER(:), ALLOCATABLE :: contents
END TYPE string_wrapper
TYPE(string_wrapper), ALLOCATABLE :: array(:)
ALLOCATE(array(4))
array(1)%contents = 'iso_varying_string'
array(2)%contents = 'still'
array(3)%contents = 'lives!'
array(4)%contents = '(sort of...)'
If you wanted to, with a bit of data hiding, some appropriate structure constructors, user defined operators and assignment, a few "forwarding" procedures as equivalents for the various intrinsics and a dash of user defined type io (when supported) you'd get something similar to what you were originally expecting in a relatively seamless way, including (if you really wanted) an elemental equivalent of TRIM.
What I'm describing is essentially an updated implementation of varying_string from iso_varying_string, that wraps a scalar deferred length character component rather than the customary array of single characters and, as a result, could be much more "natural". Someone may have already done it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, as Ian said, we're going to need an updated version of iso_varying_string for that purpose (my suggested name is iso_module_for_yet_another_incomplete_feature)... Hopefully, it will be added to the language by the Fortran 2022 standard.
Thanks for the help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page