【问题标题】:What happens with allocatable components of derived types when i use automatic reallocation?当我使用自动重新分配时,派生类型的可分配组件会发生什么情况?
【发布时间】:2014-11-04 21:46:59
【问题描述】:

在我的程序中,我想创建一个容器类型,其中包含某个派生类型的数组。我想为容器添加类型绑定过程,该过程在数组的所有组件上调用过程。由于数组的大小不同,我尝试使用自动重新分配功能。我遇到了可分配字符的问题。

这是一个小sn-p,显示设置:

module realloc_test                                                                                                                                                                                                
  implicit none                                                                                                                                                                                                    

  type :: number_t                                                                                                                                                                                                 
    character(:), allocatable :: number_c    ! this does not work                                                                                                                                                                              
!    character(len=10)         :: number_c   ! this works
    integer                   :: number_i                                                                                                                                                                                            
  end type number_t                                                                                                                                                                                                

  type number_container                                                                                                                                                                                            
    integer :: listsize                                                                                                                                                                                            
    type(number_t), allocatable, dimension(:) :: all_numbers                                                                                                                                                       
  contains                                                                                                                                                                                                         
    procedure add                                                                                                                                                                                                  
  end type number_container                                                                                                                                                                                        

contains                                                                                                                                                                                                           

  subroutine add (this, number_in)                                                                                                                                                                                 
    class(number_container), intent(inout) :: this                                                                                                                                                                 
    type(number_t), intent(inout) :: number_in                                                                                                                                                                     

    if (.not. allocated(this%all_numbers)) then                                                                                                                                                                    
      allocate(this%all_numbers(1), source = number_in)                                                                                                                                                            
      this%listsize = 1                                                                                                                                                                                            
    else  
      ! reallocate -> add entry                                                                                                                                                                                                         
      this%all_numbers = [ this%all_numbers, number_in ]                                                                                                                                                           
      this%listsize = SIZE (this%all_numbers)                                                                                                                                                                      
    end if                                                                                                                                                                                                         
  end subroutine add                                                                                                                                                                                               

end module realloc_test                                                                                                                                                                                            

program testprog                                                                                                                                                                                                   
  use realloc_test                                                                                                                                                                                                 
  implicit none                                                                                                                                                                                                    

  integer :: i                                                                                                                                                                                                     
  type(number_t) :: one, two, three, four                                                                                                                                                                          
  type(number_container) :: number_list                                                                                                                                                                            

  one = number_t ('one', 1)                                                                                                                                                                                        
  two = number_t ('two', 2)                                                                                                                                                                                        
  three = number_t ('three', 3)                                                                                                                                                                                    
  four = number_t ('four', 4)                                                                                                                                                                                      

  call number_list%add(one)                                                                                                                                                                                        
  call number_list%add(two)                                                                                                                                                                                        
  call number_list%add(three)                                                                                                                                                                                      
  call number_list%add(four)                                                                                                                                                                                       

  do i = 1, number_list%listsize                                                                                                                                                                                   
    print*, number_list%all_numbers(i)%number_c                                                                                                                                                                    
    print*, number_list%all_numbers(i)%number_i                                                                                                                                                                    
  end do                                                                                                                                                                                                           
end program testprog  

我用 ifort 编译,使用

-assume realloc_lhs

启用自动重新分配。输出内容为:

           1
 ??n
           2

           3
 four
           4

最后一个条目显示正确。复制数组的旧部分似乎会导致可分配组件出现问题。当我使用固定字符长度时,我不会遇到麻烦。当以这种方式使用自动重新分配时,究竟会发生什么?还有其他选择可以更安全地执行此操作吗?

【问题讨论】:

  • 前段时间我遇到了一个不幸的错误。我希望他们在新版本中声称完全支持 Fortran 2003 时会修复它,但他们还没有。

标签: fortran fortran2003


【解决方案1】:

我认为您看到了 https://software.intel.com/en-us/articles/incorrect-results-assigning-array-constructor-with-allocatable-components 中描述的编译器错误的后果。此错误仍在 ifort 15.0.0 中。

该链接中显示的解决方法是在最终分配给可分配组件之前使用临时构建数组。

【讨论】:

    猜你喜欢
    • 2020-03-17
    • 2012-04-26
    • 1970-01-01
    • 2016-04-29
    • 2013-05-01
    • 2018-11-22
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多