- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Suppose I have this:
integer x(100)
call xprint(x(23:70) )
end
subroutine xprint(x)
integer x(*)
end subroutine
Normally I would have to ALSO tell it how many elements of X to print.
But I was wondering if there is a subroutine call that would actually tell me how many elements I am passing?
UBOUND and SIZEOF do not work here. I get a compiler error.
If I tell the internal subroutine a fixed number of elements, x(1:20) for example,
then it will use that number, and does not know any thing about the actual size passed to it.
Maybe that is a future enhancement?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What happens if you use
INTEGER X(:)
in the subroutine? I believe this behaves differently to the older way you have declared it.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortran 90 introduced the concept of assumed shape. If your subroutine xprint has an explicit interface (perhaps because it is in a module), then you could use an assumed shape declaration (see the colon in the array specification in the following example) for the array argument - and then the compiler will automatically arrange for the shape of the actual argument to be accessible via the dummy argument
SUBROUTINE xprint(x) INTEGER :: x(:) PRINT "('The size of x is ',I0)", SIZE(x) END SUBROUTINE xprint
Note that "assumed shape" does not mean "assumed bounds" - for the call in your example the lower bound of the dummy argument x in the above will be 1 (you can specify a different lower bound to use if you want) and the upper bound will be 48.
In your original example you used an assumed size argument, with the * array specifier. Unlike assumed shape, for an assumed size argument the compiler does not automatically arrange for that size information to be accessible via the dummy argument, hence you can't do operations on that array that implicitly require that size. The programmer needs to arrange for that size information to be explicitly communicated in some other way.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, I tried it, but then I get this ERROR 7978
"Interface missing from source file"
error #7978: Required interface for passing assumed shape array is missing from original source
compilation aborted for C:\Users\billsincl\Downloads\test45_0 (1).f90 (code 1)
Why would having it in the MAIN program make any difference?
It works when the CALLING program is in a subroutine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...or put it in a module.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Put the SUBROUTINE in a module?
Well, I will try that - but does the compiler REQUIRE that specifically?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Either you put the subroutine into a module, which is then used by the main program (which then knows the interface for the subroutine), or you explicitly provide the interface information as I did in my example. Both ultimately provide the main program with the details of the arguments that the subroutine expects, and so eliminates the error that you reported that the interface was missing.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
module mod001 CONTAINS ! <----- subroutine xprint(x) integer :: x(:) nx=size(x) print *,"nx=",nx end subroutine end module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
billsincl,
I think I've suggested this to you before, please take the time to study the books recommended by Dr Fortran in his blog at https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world. I feel in spite of the best intentions of good, honest folks providing earnest responses to inquiries, the comments in this forum should be viewed more as supplemental material rather than as a primary learning source. You'd do yourself a great favor if you can take the time to review the material on Fortran 90 onwards in detail. As you know, you'll then be reminded of the power and flexibility of assumed shape arrays:
MODULE m IMPLICIT NONE PRIVATE PUBLIC :: xprint CONTAINS SUBROUTINE xprint(x, lb) !.. Argument list INTEGER, INTENT(IN) :: lb INTEGER, INTENT(IN) :: x(lb:) !.. PRINT *," Size of x: ", SIZE(x) PRINT *," Lower bound of x: ", LBOUND(x) PRINT *," Upper bound of x: ", UBOUND(x) !.. RETURN END SUBROUTINE END MODULE m PROGRAM p USE m, ONLY : xprint IMPLICIT NONE INTEGER, PARAMETER :: LL = -10 INTEGER, PARAMETER :: EXT = 99 INTEGER :: x(LL:LL+EXT) INTEGER :: Id Id = 12 CALL xprint(x(Id:Id+47), Id) STOP END PROGRAM p
Size of x: 48 Lower bound of x: 12 Upper bound of x: 59
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OH sure, I am aware of the textbooks - -
Its just getting hold of of them, and gleaning out the relevant info thats tricky.
Sometimes they dont give you very direct answers, that why I have to resort to this forum.
I would take a college course if one was available in these parts.
Thanks for your input ! !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will certainly study that.
Much more informative than the textbooks I have looked at.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bill,
There are limits to how effective the (:) array syntax is, as the following example shows that the convenience of F90 style array size info is limited only to the size and not the section information.
module info contains subroutine xprint(x) integer x(:) PRINT *," Size of x: ", SIZE(x) PRINT *," Lower bound of x: ", LBOUND(x) PRINT *," Upper bound of x: ", UBOUND(x) end subroutine xprint end module info use info integer x(100) call xprint(x(23:70) ) end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I will try both approaches.
It does not seems obvious to me right offhand which is better.
Thanks for your feedback !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
billsincl wrote:
OK, I will try both approaches.
It does not seems obvious to me right offhand which is better.
Thanks for your feedback !
Again, my message can be summed up in 3 words: details, details, details! I deliberately didn't point our particular details in my example in Quote #11 in order to encourage Bill and others to look them up from better sources such as Dr Fortran blog, books recommended therein, and technical papers, etc.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page