Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29386 Discussions

Passing integer constants thru subroutine calls

bradmull
Beginner
460 Views

Hi Dr. Fortran;

In this source code I'm converting, I came across this sort of thing:

Call SUB1(42,1000,32657) ! probably bad pratice

And in the subroutine SUB1 the arguments are typed as follows:

Integer(2) arg1

integer(4) arg2

integer(8) arg3

Now in the constants that are passed to SUB1, how does the compiler know whattype of integer to use? Does it automaticallymake themlong enough to fit? I can see where there could be some pitfalls in mis-matched argument types.

With Real constants, one can perhaps get around this problem by saying 1.E0 or 1.D0, etc, so the compiler knows how to set up the arguments. But we don't have a useful way of typing them that wayfor integers. I guess one coulddo the following:

Integer(2) I42/42/

integer(4) I1000/1000/

integer(8) I32657/32657/

And then call SUB1 with those variables -

CALL SUB1(I42,I1000,I32657)

Anyway, what does the called routine assume about the types of integers being passed to it?

You used to have an interface checking feature, (generate/interface) but someone told me that doesn't work any more.

0 Kudos
2 Replies
TimP
Honored Contributor III
460 Views
You could specify an integer(8) constant like 32657_8, or by making it a named PARAMETER
integer(8), parameter :: I32657=32657
Of course, it would theoretically be more portable to use a named kind parameter.
If you restrict your application to little-endian platforms, a wider typed integer constant will work when received as a narrower integer type, but there's little excuse to take the risk, when use of interface blocks or modules will protect against errors and portability problems.
Steve has discussed -gen-interfaces/-warn interfaces, and it is written up in ifort -help as well as in the .pdf and .chm help files.
0 Kudos
Steven_L_Intel1
Employee
460 Views
Interface checking is still there and it works.

If you don't specify a type otherwise, you'll get INTEGER(4) for integer constants. It's generally harmless to pass these to arguments accepting them as INTEGER(2) or (1) as long as you don't go outside the range. Tim's suggestions on using INTEGER(8) constants are good.

If there is an explicit interface visible for the called routine, then the compiler will, as an extension, convert integer constants to the target type.

I strongly recommend using explicit interfaces in your code. Ideally, called routines would be in modules that you USE, or are contained routines. Writing an INTERFACE block (and then including it somehow) is a less desirable choice.
0 Kudos
Reply