Намерение Fortran (inout) против намерения пропуска - PullRequest
31 голосов
/ 21 мая 2010

Хорошая практика диктует, что аргументы подпрограммы в Фортране должны иметь каждое заданное намерение (т.е. 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), и аргумента без указанного намерения?Есть ли что-то, о чем мне следует беспокоиться, если я переоснащаю свои намерения более старым, свободным от намерений кодом?

Ответы [ 3 ]

21 голосов
/ 21 мая 2010

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

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

6 голосов
/ 21 мая 2010

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

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

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

3 голосов
/ 15 апреля 2016

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

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

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

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

...