Fortran EQUIVALENCE оператор с длиной массива из подпрограммы ввода - PullRequest
2 голосов
/ 25 марта 2020

Я модернизирую какой-то старый код на Фортране и не могу где-то избавиться от выражения эквивалентности (короче говоря: его смешанное использование настолько запутанно, что для преобразования всего потребуется слишком много работы).

Мне нужно, чтобы длина массивов EQUIVALENCEd зависела от некоторого ввода, например, следующего кода:

program test_equivalence                                                
      implicit none                                                     

      type :: t1                                                        
          integer :: len = 10                                           
      end type t1                                                       

      type(t1) :: o1                                                    


      call eqv_int(o1%len)                                              
      call eqv(o1)                                                      

      return                                                 

      contains                                                          
          subroutine eqv_int(len)                                       
             integer, intent(in) :: len                                 
             integer :: iwork(len*2)                                    
             real(8) :: rwork(len)                                      
             equivalence(iwork,rwork)                                   

             print *, 'LEN = ',len                                      
             print *, 'SIZE(IWORK) = ',size(iwork)                      
             print *, 'SIZE(RWORK) = ',size(rwork)                      
          end subroutine eqv_int                                        

          subroutine eqv(o1)                                            
             type(t1), intent(in) :: o1                                 

             integer :: iwork(o1%len*2)                                 
             real(8) :: rwork(o1%len)                                   
             equivalence(iwork,rwork)                                   

             print *, 'LEN = ',o1%len                                   
             print *, 'SIZE(IWORK) = ',size(iwork)                      
             print *, 'SIZE(RWORK) = ',size(rwork)                      
          end subroutine eqv                                            
end program test_equivalence                                            

Эта программа создаст массивы 0 длины с gfortran 9.2.0. Это вывод:

 LEN =           10
 SIZE(IWORK) =            0
 SIZE(RWORK) =            0

 LEN =           10
 SIZE(IWORK) =            0
 SIZE(RWORK) =            0

Тот же код вернет Array 'rwork' at (1) with non-constant bounds cannot be an EQUIVALENCE object при компиляции с gfortran 5.3.0, предупреждение исчезает с gfortran 6.2.0, но размер массивов всегда равен 0. Итак возможно ошибка компилятора?

1 Ответ

0 голосов
/ 25 марта 2020

Исходный код действительно не является допустимой программой на Фортране. Чтобы быть определенным c, он нарушает пронумерованное ограничение C8106 Фортрана 2018:

объект эквивалентности не должен быть обозначением с основанием объект, который является .. автоматическим c объектом данных ..

Будучи пронумерованным ограничением, компилятор должен способен обнаруживать это нарушение. Если такой возможности нет, то это недостаток компилятора (ошибка). Быть «способным» не означает делать это по умолчанию, поэтому, пожалуйста, внимательно посмотрите, есть ли варианты, которые приводят к этому обнаружению. Кто-то, знакомый с внутренностями G CC, может дать дополнительную информацию здесь.

Поскольку исходный код не является допустимой программой на Фортране, компилятору разрешено рассматривать массивы нулевого размера, если он пропустил нарушение обнаружение.

...