Цитата(popovda @ 15.5.2007, 16:08 ) | Сдается мне, что второй способ предпочтительнее, т.к. идет из HPF и только он может использоваться в процедурах без побочного эффекта для возврата массива |
Ну, процедуры-не-функции тоже могут быть чистыми, даже если будут меня больше одного параметра ;-)
| Код | pure subroutine MySubRout1(b, res) real, dimension(:),intent(in) :: b; real, dimension(:),intent(out) :: res; ..................................... res = AnyFunc_or_operation(b); ! Предопределенный массив ..................................... end subroutine MySubRout1;
|
Цитата(popovda @ 15.5.2007, 16:08 ) | | память для переменных функции выделяется, насколько я помню стандарт, при первом вызове и освобождается при завершении работы программы |
Хм.. Возможно. Но одно дело память для ссылки, а другое дело память для массива у этой ссылки. Т.е. если возвращается массив неизвестной длины, то возвращается ссылка (да как и всегда), а выделение памяти будет каждый раз своё.
Цитата(FatalError @ 15.5.2007, 22:27 ) | | Автоматический массив создается при входе в функцию/процедуру и должен при выходе из нее разрушаться. |
Это не совсем автоматический массив функции, это же сама функция. Проверь, например, когда используешь MatMul, памяти ведь нужно в два раза больше. Так и тут: массив функции живёт, пока результат функции не присвоится куда-нибудь или не перестанет использоваться.
Цитата(popovda @ 16.5.2007, 17:35 ) | | Кроме того, будет фрагментация памяти или нет - зависит от реализации компилятора. |
При использовании многих функций, получается, что фрагментация памяти как бы будет. Да что там говорить, "вместо" процедур почти все встроенные подпрограммы являются функциями! И это то в божном Fotran! Казалось бы, зачем, почему.. Да потому что по-другому быть не может. Казалось бы, здесь не будет выделений памяти вообще:
| Код | call MatMul(MatrixA, MatrixB, ResultMatrix)
|
а тут -- может и быть:
| Код | ResultMatrix = MatMul(MatrixA, MatrixB)
|
Но.. первый вариант не подходит для:
| Код | call MatMul(MatrixA, MatrixB, MatrixA)
|
Цитата(FatalError @ 15.5.2007, 22:27 ) | | Автоматический массив создается при входе в функцию/процедуру и должен при выходе из нее разрушаться. Если только он не прописан с атрибутом SAVE. Без SAVE, мне кажется, данные просто потеряются. |
Но к массиву функции это не относится.
Интересно, что для рекурсии result обязателен. Это как бы переменная каждого экземпляра функции.
Добавлено через 10 минут и 57 секунд А вообще, мораль такова. Если функция в конечном итоге присваивается к одному из своих аргументов, то выделения памяти не избежать.
| Код | A = Func(A, B) ! Массивы
|
Но до чего обидно, если функция эта имеет такую природу:
| Код | A = SumOfElements(A, B) ! = MaxAbsElements(A, B)
|
и т.п. Ведь компилятору будет очень сложно распознать. Ничего страшного, в том числе и для этого придумали элементные функции. И если тут выделение памяти будет:
то тут -- не факт:
Думаю, разница улавливается прозрачно.
Нелишнее выделение памяти -- элемент искусства разработчиков компилятора.
| Код | A = MatMul(A, B) + MatMul(B, C)
|
|