This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Question on allocating string arrays, primarily with a declaration where LEN=*


Question 1:

When compiled with gfortran 5.4.0:

   $gfortran -std=f2008 -Wuninitialized aaa.f90

I get an unexpected warning that 'help_text' is used uninitilialized.

   >aaa.f90:4:0:
   >character(len=:),allocatable :: help_text(:)
   >^
   >Warning: '.help_text' is used uninitialized in this function
[-Wuninitialized]

Using the following example program:

program testit
implicit none
character(len=:),allocatable :: help_text(:)
integer                      :: i
   help_text=[ CHARACTER(LEN=80) :: &
   'defines length and size with different length expressions. Yeah!',&
   '   aaaaaaaaaaaaa',&
   '   bbbbbbbbbbbbbbbbb',&
   '   ddddddddddddddddddddd',&
   '']
   write(*,'(a)')repeat('=',len(help_text(1))) !assumed at least size one
   write(*,'(a)')(trim(help_text(i)),i=1,size(help_text))
   write(*,'(a)')repeat('=',len(help_text(1))) !assumed at least size one
end program testit

Is this a misleading message or am I missing something?
 

Question 2: 
   I thought (perhaps incorrectly) that everything used to initialize
   an allocatable string array had to be of the same constant length
   when LEN=* was used in the initialization. But when I initialize
   using allocatable variables instead of getting an error it works,
   but sets everthing to the length of the first expression/variable. Is
   this non-standard?  I can shorten the example, but you can see in the
   following program (which runs) that I initialized using functions
   returning different lengths and with allocatable variables of
   different lengths with the -std=f2008 switch and it works (sort of -
   since it does not fail I would expect the length to be the length of
   the longest variable):

program rabbithole
implicit none
character(len=:),allocatable    :: help_text(:)
integer                         :: i,j
integer                         :: ii
integer,allocatable             :: sizes(:)
character(len=*),parameter      :: pten='abcdefghij'
character(len=*),parameter      :: ptwenty='abcdefghijabcdefghij'
character(len=:),allocatable    :: all1,all2
character(len=10)               :: cten='abcdefghij'
character(len=20)               :: ctwenty='abcdefghijabcdefghij'
!---------------------------------------------------------------------------
----
   write(*,*)'LEN=* WORKS IF ALL STRINGS ARE THE SAME LENGTH, LEN(), SIZE(),
ALLOCATED() OK AS EXPECTED'
   all1='ABCDEFGHIJ'
   all2='abcdefghijABCDEFGHIJ'
   write(*,*)'ALLOCATED?',allocated(help_text)
   help_text=[ CHARACTER(LEN=*) :: & 
   'defines length and size. All strings have to be same length ?   ',&
   '   aaaaaaaaaaaaa                                                ',&
   '   bbbbbbbbbbbbbbbbb                                            ',&
   '   ddddddddddddddddddddd                                        ',&
   '1234567890123456789012345678901234567890123456789012345678901234']
   if(allocated(help_text))then
      write(*,*)'ALLOCATED?',allocated(help_text)
      if(size(help_text).ge.1)then
         write(*,*)'SIZE',size(help_text)
         write(*,*)'LEN ',len(help_text(1))
      else
         write(*,*)'ERROR: NO SIZE'
      endif
   else
      write(*,*)'ERROR: NOT ALLOCATED'
   endif
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)' GET ERROR IF DIFFERENT LENGTH CONSTANT EXPRESSIONS ARE USED'
   !!    help_text=[ CHARACTER(LEN=*) :: '2345678901234', '12345678901234']
   !!                                                   1
   !!Error: Different CHARACTER lengths (13/14) in array constructor at (1)
   !!
   write(*,*)' BUT OK WHEN LENGTHS ARE SAME'
   help_text=[ CHARACTER(LEN=*) :: '12345678901234', '12345678901234']
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)'TEST NULL STRING'
   help_text=[ CHARACTER(LEN=*) :: '']
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)'TEST STRINGS RETURNED BY FUNCTION THAT ARE THE SAME LENGTH
LEN=*'
   help_text=[ CHARACTER(LEN=*) :: lenset('12345678901234567890',30),
lenset('12345678901234567890',30)]
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)'TEST STRINGS RETURNED BY FUNCTION THAT ARE DIFFERENT LENGTHS
LEN=*'
   help_text=[ CHARACTER(LEN=*)
::lenset('12345678901234567890',10),lenset('12345678901234567890',20)]
   call printit()
   help_text=[ CHARACTER(LEN=*) ::
lenset('12345678901234567890',20),lenset('12345678901234567890',10)]
   call printit()
   write(*,*)'Appears to take length from first variable defined???. Not an
error???'
!---------------------------------------------------------------------------
----
   write(*,*)'PARAMETER VERSUS VARIABLE VERSUS ALLOCATABLE LEN=*'
   !! help_text=[ CHARACTER(LEN=*) :: pten, ptwenty ] ! Error: Different
CHARACTER lengths (10/20) in array constructor at (1)
   !! help_text=[ CHARACTER(LEN=*) :: cten, ctwenty ] ! Error: Different
CHARACTER lengths (10/20) in array constructor at (1)
   help_text=[ CHARACTER(LEN=*) :: all1, all2 ] 
   write(*,*)'works with allocatable, but not parameter or variable??'
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)'SETTING THE LENGTH WITH A CONSTANT LEN=40'
   help_text=[ CHARACTER(LEN=40) :: pten, ptwenty ] 
   call printit()
   help_text=[ CHARACTER(LEN=40) :: cten, ctwenty ] 
   call printit()
   help_text=[ CHARACTER(LEN=40) :: all1, all2 ] 
   call printit()
!---------------------------------------------------------------------------
----
   write(*,*)'SETTING THE LENGTH WITH A VARIABLE LEN={0,1,4,10,20,50}'
   sizes=[0,1,4,10,20,50]
   do j=1,size(sizes)
      ii=sizes(j)
      !! THIS WORKED WHEN USED CONSTANT INSTEAD OF VARIABLE?
      !!help_text=[ CHARACTER(LEN=II) :: pten, ptwenty ] Error: size of
variable `A.60' is too large
      !!call printit()
      help_text=[ CHARACTER(LEN=II) :: cten, ctwenty ] 
      call printit()
      help_text=[ CHARACTER(LEN=II) :: all1, all2 ] 
      call printit()
   enddo
!---------------------------------------------------------------------------
----
   write(*,*)'DOES LEN HAVE TO REDUCE TO A CONSTANT OR NOT?'
   write(*,*)'ENTER LENGTH '  ! enter a negative number to be mean
   read(*,*)ii
   !!help_text=[ CHARACTER(LEN=II) :: pten, ptwenty ] Error: size of
variable `A.60' is too large
   !!call printit()
   help_text=[ CHARACTER(LEN=II) :: cten, ctwenty ] 
   call printit()
   help_text=[ CHARACTER(LEN=II) :: all1, all2 ] 
   call printit()
!---------------------------------------------------------------------------
----
contains 
subroutine printit()
   write(*,'(a)')repeat('=',len(help_text(i)))
   write(*,'(a)')(trim(help_text(i)),i=1,size(help_text))
   write(*,'(a)')repeat('=',len(help_text(i)))
end subroutine printit
function lenset(line,length) result(strout) ! return string with length
LENGTH
character(len=*),intent(in)  ::  line
integer,intent(in)           ::  length
character(len=length)        ::  strout
   strout=line
end function lenset
end program rabbithole
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!

 
I get different results with different compilers and the "new" features
with allocatable character arrays and initializing them with LEN=*
versus LEN=: versus no length in the declaration is a feature I have
only recently been using; but I thought the standard was that when LEN=*
was used everything in a declaration had to be of the same length and
that perhaps the length had to be a constant at compilation time; but the
test contradicts this length restriction when initializing with allocatable
expressions,
and allows lengths determined at run time (I thought I had to use LEN=: for
that). Is
this an extension/bug or allowed by the standard?

Thanks for any help clarifying this for me.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]