Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29286 Discussions

Q about passing array boundaries or sizes

WSinc
New Contributor I
1,482 Views

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?

 

0 Kudos
16 Replies
DavidWhite
Valued Contributor II
1,482 Views

What happens if you use

INTEGER X(:)

in the subroutine?  I believe this behaves differently to the older way you have declared it.

David

0 Kudos
IanH
Honored Contributor III
1,482 Views

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.

0 Kudos
WSinc
New Contributor I
1,482 Views

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.

0 Kudos
DavidWhite
Valued Contributor II
1,482 Views

You can add an interface to your program as attached.

or put CONTAINS before the subroutine and the END for the program after the end of the subroutine (makes it internal to the program).

 

0 Kudos
IanH
Honored Contributor III
1,482 Views

...or put it in a module.
 

0 Kudos
WSinc
New Contributor I
1,482 Views

Put the SUBROUTINE in a module?

 

Well, I will try that - but does the compiler REQUIRE that specifically?

0 Kudos
DavidWhite
Valued Contributor II
1,482 Views

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

0 Kudos
WSinc
New Contributor I
1,482 Views

Can you give me an example of how you did that?

 

Just stuffing the whole subroutine into a MODULE generated BOUCOUP error messages.

0 Kudos
IanH
Honored Contributor III
1,482 Views
    module mod001
    CONTAINS   ! <-----
    subroutine xprint(x)
    integer :: x(:)
    nx=size(x)
    print *,"nx=",nx
    end subroutine
    end module

 

0 Kudos
FortranFan
Honored Contributor III
1,482 Views

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

 

0 Kudos
WSinc
New Contributor I
1,482 Views

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 ! !

0 Kudos
Steven_L_Intel1
Employee
1,482 Views
0 Kudos
WSinc
New Contributor I
1,482 Views

I will certainly study that.

Much more informative than the textbooks I have looked at.

 

0 Kudos
John_Campbell
New Contributor II
1,482 Views

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

 

0 Kudos
WSinc
New Contributor I
1,482 Views

OK, I will try both approaches.

It does not seems obvious to me right offhand which is better.

 

Thanks for your feedback !

0 Kudos
FortranFan
Honored Contributor III
1,482 Views

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.

0 Kudos
Reply