SELECT TYPE с неограниченным полиморфным указателем на переменную CHARACTER(*)

В следующем примере используются функции Fortran 2003 для определения неограниченного количества полиморфных указателей и выполнения действий на основе типа переменной, следующего за конструкцией select type. Подпрограмма handleP выводит значение аргумента в зависимости от его типа.

program example
    implicit none
    type name
        character(22) :: n
    end type

    character(len=7) :: mystring
    mystring = 'Initial'

    call handleP(mystring)
    call handleP('Initial')
    call handleP(name('Initial'))

    contains

        subroutine handleP(p)
            class(*), intent(in) :: p

            select type(p)
            type is (character(len=*))
                write(*,*) len(p), ': ', p
            class is (name)
                write(*,*) len(p%n), ': ', p%n
            class default
                write(*,*) 'Unknown type'
            end select
        end subroutine

end program example

Компиляция с gfortran версии 4.8 дает следующий результат:

       7 : Initial
       0 :
      22 : Initial

Итак, с call handleP(mystring) все работает как положено, а с call handleP('Initial') печать не работает. Вызов с аргументом type(name) также работает.

Является ли поведение с call handleP('Initial') ошибкой gfortran или я делаю что-то не так? Если это ошибка, что я могу сделать, чтобы предотвратить это?


person Holger    schedule 02.06.2014    source источник
comment
Один из ваших операторов защиты типа является синтаксической ошибкой. Он использует спецификацию предполагаемой длины (*) - это должна быть отложенная длина (используйте :). Если gfortran принимает это, то это ошибка компилятора.   -  person IanH    schedule 02.06.2014
comment
@IanH Верна ли отложенная длина? Из F2008 4.4.3.2 Значение параметра типа char-length, равное *, имеет следующие значения... Если используется в спецификации типа оператора защиты типа, ассоциированный объект принимает свою длину из селектора. Документация NAG также поддерживает *.   -  person francescalus    schedule 02.06.2014
comment
Вы правы - я перепутал предполагаемое и отложенное.   -  person IanH    schedule 03.06.2014
comment
Спасибо за ваши ответы. Почитав об ошибках gcc, я предположил, что это ошибка gfortran. Gfortran, похоже, еще не очень способен передавать строки с полиморфными указателями.   -  person Holger    schedule 06.06.2014


Ответы (2)


Я просто хочу, чтобы все знали, что проблема устранена в gFortran 4.9.3-1, который поставляется с текущей установкой MinGW.

person Freemongo    schedule 03.06.2016

Это, вероятно, то, что вы хотите:

program example
    implicit none
    type name1
        character(22) :: n
    end type

    character(len=7) :: mystring
    mystring = 'Initial'

    call handleP(mystring)
    call handleP('Initial')
    call handleP(name1('Initial'))

    contains

        subroutine handleP(p)
            class(*), intent(in) :: p

            select type(p)
            type is (character(len=*))
                write(*,*) len(p), ': ', p
            class is (name1)
                write(*,*) len(trim(adjustl(p%n))), ': ', p%n
            class default
                write(*,*) 'Unknown type'
            end select
        end subroutine

end program example

Второй вызов не работает, так как Initial не является переменной. 22 до этого были просто длиной, которую вы определили в объявлении типа. Поэтому я отрегулировал длину.

person PeMa    schedule 02.06.2014
comment
Спасибо за ваш ответ. Но мои вопросы были больше по второму случаю. Теперь я совершенно уверен, что передача «Initial» в handleP должна быть возможна, потому что это работает и для действительных и целых чисел. - person Holger; 06.06.2014
comment
Точно, извините за путаницу. На самом деле вы правы. Я только что попробовал. Компилятор Intel дает то, что вы ожидали. Кстати. с компилятором PGI я получаю только ошибку сегментации. - person PeMa; 06.06.2014