Подтвердить что ты не робот

Фортран намерение (inout) против упущения намерений

Хорошая практика диктует, что аргументы подпрограммы в Fortran должны иметь определенный намерение (т.е. intent(in), intent(out) или intent(inout), как описано этот вопрос):

subroutine bar (a, b)
    real, intent(in) :: a
    real, intent(inout) :: b
    b = b + a
    ...

Однако не указывается намерение Fortran:

subroutine bar (a, b)
    real, intent(in) :: a
    real :: b
    b = b + a
    ...

Существуют ли какие-либо реальные различия, кроме проверки времени компиляции для аргумента, указанного как intent(inout), и аргумента без указанного намерения? Есть ли что-нибудь, о чем я должен беспокоиться, если я доработаю намерения до более старшего, без намерения, кода?

4b9b3361

Ответ 1

В соответствии с Руководством по Fortran 2003 от Adams и др. существует одно отличие между аргументом (inout) и не аргументом без указания намерения. Фактический аргумент (т.е. В вызывающем) в случае намерения (inout) всегда должен быть определяемым. Если намерение не указано, аргумент должен быть определен, если выполнение подпрограммы пытается определить фиктивный аргумент. определяемое значение, устанавливающее значение: dummy_arg = 2.0. Очевидно, что фактический аргумент должен быть переменной, если это сделано. Для намерения (inout) фактический аргумент должен быть определяемым независимо от того, выполняет ли это подпрограмма. Без указанного намерения это зависит от того, что происходит при этом конкретном вызове подпрограммы - если подпрограмма не определяет переменную, это нормально; если это так, то есть проблема - такие случаи, как запись в фактический аргумент, который является константой, будут, очевидно, вызывать проблемы.

Это не означает, что компилятор будет диагностировать все эти случаи - то, что стандарт требует от компилятора для диагностики, - это другая проблема. В момент компиляции было бы почти невозможно обнаружить все ошибки требования, не указанные в запросе, поскольку нарушения зависят от потока времени выполнения кода. Это намного проще для компилятора, чтобы диагностировать случай намерения (inout) и предупредить вас о проблемах с кодом.

Ответ 2

В вашем вопросе возникает вопрос, может ли вы столкнуться с различием в поведении, если ваш код передает PARAMETER в качестве фактического аргумента, который ваша подпрограмма затем пытается записать. Без объявления INTENT компилятор может отпустить это, что приведет к нечетному поведению. С объявлением я ожидаю ошибку времени компиляции.

Вы и я можем подумать, что нет никакой разницы между INOUT и объявлением INTENT, но не забывайте, что там много старых программ Fortran, и что совместимость со старыми языковыми версиями является важной особенностью новых стандартов, Если это было правильно (но изворотливое) FORTRAN77, то многие люди ожидают, что их код останется верным (все еще изворотливым) с компилятором Fortran 90+.

Быстрое считывание стандарта 2003 указывает на то, что существует разница между INOUT и INTENT, но требуется более тщательное чтение. Если вы проверите это, дайте нам знать ваши выводы; если у меня будет время позже, я сам проверю это и дам вам знать.

Ответ 3

Чтобы понять роль намерения в/из, вам нужно знать, что внутри, Fortran эффективно передает переменные по ссылке. Это не всегда совпадает с фактическим передачей по ссылке.

Если вы передаете внутреннюю часть 2-мерного массива подпрограмме, то есть: data(i1:i2, j1:j2), то Fortran копирует эти данные в смежный раздел памяти и передает новый адрес в подпрограмму. По возвращении данные копируются обратно в исходное местоположение.

Указав INTENT, компилятор может знать, чтобы пропустить одну из операций копирования.

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