From: Ralph Kube on
Hello everyone!
I just found out that Fortran distinguishes between passing a variable
and actual numbers to a subroutine.

F.eks. writing

integer, dimension(2) ddims
ddims(1) = 64
ddims(2) = 64
CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, ddims, error)

works perfectly, but

CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, (/64,64/), error)

results in a compiler error: ( I am using the intel fortran compiler v.
11.1)
../initl.f90(175): error #6285: There is no matching specific subroutine
for this generic subroutine call. [H5DREAD_F]
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, theta(1:My, 1:Nx),
(/My,Nx/), error)

So when I declare and initialize the array, the call works, but passing
the same numbers instead results in an error.

Coming from the C/Python world this rather astonishes me. Is this
because in Fortran subroutines get a reference rather than a value
passed by default?
I would have also expected a segfault when passing a wrong reference
rather then a compiler error.
Can anybody enlighten me?

Cheers, Ralph
From: PGK on
Hi Ralph,

Unlike C, Fortran passes its procedure parameters by reference. So an
array literal will only work as an argument procedure declared intent
(in). For example, the code below will not compile with the second
call to foo uncommented - unless the dummy argument x of foo is
declared intent(in).

module m

public :: foo

contains

function foo(x) result(y)
integer, dimension(:), intent(inout) :: x
integer, dimension(size(x)) :: y
y = x + 1
end function foo

end module m

program main

use m
integer, dimension(4) :: f = 19, g
! g = foo( f )
g = foo( (/19,19,19,19/) )

print *, f
print *, g

end program main

You will get a similar issue in C++ when calling "bar" with a literal
(it needs a "const" qualifier)
int bar(int &x){ return 9; }

Cheers,
Graham

From: James Van Buskirk on
"Ralph Kube" <rku000(a)post.uit.no> wrote in message
news:hf2r0i$o31$1(a)inn.uit.no...

> I just found out that Fortran distinguishes between passing a variable and
> actual numbers to a subroutine.

> integer, dimension(2) ddims
> ddims(1) = 64
> ddims(2) = 64
> CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, ddims, error)

> works perfectly, but

> CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, (/64,64/), error)

> results in a compiler error: ( I am using the intel fortran compiler v.
> 11.1)
> ./initl.f90(175): error #6285: There is no matching specific subroutine
> for this generic subroutine call. [H5DREAD_F]
> call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, theta(1:My, 1:Nx),
> (/My,Nx/), error)

Probably a simple mistake on your part. Can you give us the
declarations of dset1_id, H5T_NATIVE_DOUBLE, bufnew, error, dset_id,
and theta? Also the specification parts of the specific subroutines
which generic h5dread_f may resolve to?

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Richard Maine on
Ralph Kube <rku000(a)post.uit.no> wrote:

> I just found out that Fortran distinguishes between passing a variable
> and actual numbers to a subroutine.
>
> F.eks. writing
>
> integer, dimension(2) ddims
> ddims(1) = 64
> ddims(2) = 64
> CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, ddims, error)
>
> works perfectly, but
>
> CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, (/64,64/), error)
>
> results in a compiler error: ( I am using the intel fortran compiler v.
> 11.1)
> ./initl.f90(175): error #6285: There is no matching specific subroutine
> for this generic subroutine call. [H5DREAD_F]
> call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, theta(1:My, 1:Nx),
> (/My,Nx/), error)
>
> So when I declare and initialize the array, the call works, but passing
> the same numbers instead results in an error.

I'd like to see a complete sample, including the subroutine and the
generic inerface block. One could cut things way down to make such a
sample, as the subroutine doesn't actually have to do anything. I'm
wondering if the problem doesn't lie in something not shown.

After all, when an error message complains about the specific
subroutines, it naturally makes me want to see those subroutines in
order to diagnose things.

There are differences between passing a variable and an expression as an
actual argument (the above array constant is just a trivial case of an
expression), but they are not differences that should affect generic
resolution. They just have to do with the INTENT attribute. An
expression is not modifiable and cannot be an actual argument for an
INTENT(OUT) or INTENT(INOUT) dummy. (The case of unspecified intent can
be messier). I suppose one possibility is that you might have an
inappropriate INTENT attribute for an expression actual argument. If
that were so, this error message would be a little misleading, but
that's something I could believe.

I hesitate to even mention the possibility of a compiler bug without
seeing a complete sample. It is too easy for there to be other
unconsidered factors. The above INTENT question is one that immediately
occurs to me, but there could be others that I didn't think of.

P.S. Completely irrelevant, but when I first saw the H5... in the actual
argument lists, I inadvertantly mentally transposed that to 5H... and
groaned at the thought of Hollerith actual arguments mixed with generic
resolution. If you never programmed in f66, you might not have any idea
what I'm talking about. That's ok, as it really is irrelevant. Nothing
wrong with your code in that regard. I just thought some other "old
timers" might understand my reaction and find it mildly humorous.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Steve Lionel on
Ralph Kube wrote:

> CALL h5dread_f(dset1_id, H5T_NATIVE_DOUBLE, bufnew, (/64,64/), error)
>
> results in a compiler error: ( I am using the intel fortran compiler v.
> 11.1)
> ./initl.f90(175): error #6285: There is no matching specific subroutine
> for this generic subroutine call. [H5DREAD_F]
> call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, theta(1:My, 1:Nx),
> (/My,Nx/), error)

I tried to construct an example to reproduce this problem, but couldn't.
The comments about INTENT are interesting but not relevant as INTENT
does not play in generic resolution, which is what this error message is
about.

There's an interesting thing here. Compare the call that Ralph says he
used with the one displayed in the error message - they are quite
different. If I had to guess (and I do), I'd say that My and Nx are not
default integer.

--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Software Development Products Support
http://software.intel.com/sites/support/
My Fortran blog
http://www.intel.com/software/drfortran