Вы можете использовать переменные нулевой длины для хранения промежуточных результатов, которые можно извлечь из них с помощью запросов спецификации.Время для примера:
module mod_par
implicit none
contains
pure function par(x)
double precision par
integer, intent(in) :: x
par = 1+sqrt(real(1,kind(par))+x)
end function par
end module mod_par
module mod_foo
! use mod_par
implicit none
double precision par
contains
subroutine foo(p,v)
implicit none
integer p
double precision v
character(0) sv_i(floor(par(p)))
character(floor(par(p))) sv_j(0)
logical sv_k(floor(par(p)),0)
type t
! Intentionally empty
end type t
type(t) sv_L(floor(par(p)))
type u(len)
integer, len :: len
! intentionally empty
end type u
type(u(floor(par(p)))) sv_m
double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
! double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
write(*,*) shape(z)
end subroutine foo
end module mod_foo
program bar
use mod_par
use mod_foo
implicit none
call foo(10,1.0d0)
end program bar
Это не сработало как на ifort, так и на gfortran, потому что спецификационная функция, здесь par
, должна быть PURE
, а ее интерфейс должен быть явным.Здесь par
, хотя PURE
имеет неявный интерфейс, поэтому он отклонен.На самом деле оба компилятора, похоже, запутались:
specvar.f90:21:25:
character(floor(par(p))) sv_j(0)
1
Error: Function 'par' at (1) has no IMPLICIT type
Для gfortran, и ifort говорит
specvar.f90(31): error #6404: This name does not have a type, and must have an e
xplicit type. [PAR]
type(u(floor(par(p)))) sv_m
----------------------^
Так что мы исправляем эту ошибку программирования ...
module mod_par
implicit none
contains
pure function par(x)
double precision par
integer, intent(in) :: x
par = 1+sqrt(real(1,kind(par))+x)
end function par
end module mod_par
module mod_foo
use mod_par
implicit none
! double precision par
contains
subroutine foo(p,v)
implicit none
integer p
double precision v
character(0) sv_i(floor(par(p)))
character(floor(par(p))) sv_j(0)
logical sv_k(floor(par(p)),0)
type t
! Intentionally empty
end type t
type(t) sv_L(floor(par(p)))
type u(len)
integer, len :: len
! intentionally empty
end type u
type(u(floor(par(p)))) sv_m
double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
! double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
write(*,*) shape(z)
end subroutine foo
end module mod_foo
program bar
use mod_par
use mod_foo
implicit none
call foo(10,1.0d0)
end program bar
Но теперь gfortran говорит:
specvar.f90:32:73:
double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%l
en,0)
1
Error: Variable 'sv_m' cannot appear in the expression at (1)
И ifort:
specvar.f90(31): error #6279: A specification expression object must be a dummy
argument, a COMMON block object, or an object accessible through host or use ass
ociation. [SV_M]
type(u(floor(par(p)))) sv_m
--------------------------------^
Так что у меня нет достаточно свежей версии любого из компиляторов для поддержки запросов параметров типа.Облом.Итак, мы избавляемся от этого последнего бита ...
module mod_par
implicit none
contains
pure function par(x)
double precision par
integer, intent(in) :: x
par = 1+sqrt(real(1,kind(par))+x)
end function par
end module mod_par
module mod_foo
use mod_par
implicit none
! double precision par
contains
subroutine foo(p,v)
implicit none
integer p
double precision v
character(0) sv_i(floor(par(p)))
character(floor(par(p))) sv_j(0)
logical sv_k(floor(par(p)),0)
type t
! Intentionally empty
end type t
type(t) sv_L(floor(par(p)))
type u(len)
integer, len :: len
! intentionally empty
end type u
type(u(floor(par(p)))) sv_m
! double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
write(*,*) shape(z)
end subroutine foo
end module mod_foo
program bar
use mod_par
use mod_foo
implicit none
call foo(10,1.0d0)
end program bar
И теперь оба компилятора выдают хороший код.Таким образом, вы можете видеть, что существует много способов сохранить временную целочисленную переменную в спецификациях автоматических переменных нулевой длины, которые можно использовать в дальнейших выражениях спецификации.Обратите внимание, что если вы слишком увлечетесь этим синтаксисом, вы будете часто ломать компилятор.