2016-11-19 2 views
1

У меня проблема с пониманием того, почему переменная (i), объявленная в подпрограмме, отображается в подпрограмме, но это неверно для функции (fie), что приводит к сбор ошибка. Я искал ответ, а также пытался выяснить, могу ли я найти что-то в стандарте Fortran 95, но напрасно.Правила определения области для переменных и функций в содержащихся подпрограммах

я написал небольшой пример программы:

program pgm 
    call a 
end 

subroutine a 
    implicit none 
    integer :: i 
    double precision :: fie 

    i = 7 
    call b 
    !write(*,*) fie(9) 

contains 
    subroutine b 
    double precision :: x 
    !double precision :: fie 

    x = i 
    x = x + fie(i) 
    write(*,*) x 
    end subroutine 
end subroutine 


double precision function fie(ii) 
    implicit none 
    integer, intent(in) :: ii 

    fie = ii 
end function 

При компиляции с gfortran под Cygwin (gfortran 5.4.0) Я получаю следующее сообщение об ошибке:

$ gfortran aa.f90 
aa.f90:20:15: 

    x = x + fie(i) 
       1 
Error: ‘fie’ at (1) is not a function 

При включении либо из прокомментированные строки, программа компилируется и работает правильно.

Я видел подобное сообщение об ошибке при использовании компилятора Intel (Intel Fortran 12.1.7.367, действительно довольно старый).

Похоже, что fie должен быть доступен либо в содержащейся подпрограмме, либо должен использоваться в охватывающей подпрограмме, но, как сказано, я не смог найти ответ в сети или в стандарте Fortran 95 (или, может быть, я не искал правильных слов).

Любое объяснение?

+0

Известно, что было бы лучше использовать модуль, но он является частью существующей базы кода, где детали расширены (другими). – albert

ответ

2

Самое простое исправление использовать

double precision, external :: fie 

внешний атрибут (также может быть указан в external заявлении) говорит: это процедура, я не объявить локальную переменную.

Для объявления без external, которое должно интерпретироваться как объявление функции, ссылка функции должна присутствовать внутри тела функции. Внутренние функции не учитываются. И поэтому компилятор создал локальную переменную двойной точности с именем fie.

Спасибо, чтобы IanH для соответствующего стандартного правила (с Fortran 2008 (16.5.1.4p5), но Fortran 95 будет иметь эквивалент):

Если внешние или фиктивная процедура с неявным интерфейсом , доступ к которому осуществляется через хост-ассоциацию, то он должен иметь атрибут EXTERNAL в узле определения области хоста; если он вызван как функция в , то внутренняя область видимости, ее тип и тип параметров должны быть , установленным в единице измерения хоста. Параметры типа и типа функция с атрибутом EXTERNAL устанавливается в области , если этот модуль определения явно объявляет их, вызывает функцию , обращается к функции из модуля или обращается к функции со своего хоста, где ее тип и тип параметров установлены .

Конечно, явные интерфейсы (лучше всего использовать модули) намного лучше, чем внешние функции.

+0

Я забыл о возможности «внешнего». В стандарте Fortran95 параграф «14.6.1.3 Ассоциация хозяев существует, но менее ясна, для меня, в этом отношении. – albert

Смежные вопросы