Logical Argument Size Mismatch

Logical Argument Size Mismatch

I have a call where a Logical*2 argument is passed to a subroutine expecting an (in/out) Logical*4 - a recipe for trouble as you might imagine, but the compiler doesn't whinge? Is there a compiler option that will flag this?

Edit:

Actually, this seems to be occuring and causing problems in several places...

IVF  12.1.3534.2010, on Win7 x64

12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Use the /warn:all option, and it will warn you about mismatched argument types:

Quote:

warning #6075: The data type of the actual argument does not match the definition.

Generated interface checking, on by default in a Debug configuration, will detect this. From the command line it's /warn:interface (or /warn:all).

Steve - Intel Developer Support

Thanks - these warning have brought up another question though - why is an (Int2 - 1) not an Int2? I know integers have a default kind but surely it is safer in this instance to assume the smallest kind is meant?

No, when differing data types are combined, it's done in the type with bigger range.  As far as int(2) is concerned, there hasn't been a Fortran platform which could do it more efficiently in 16 bits (aside from memory usage) for over 2 decades.

Re-reading my comment I guess I wasn't clear. Suppose you have:

Subroutine MySub(I2)

which you then call with:

 Call MySub(I2 -1)

If your default integer kind is I4, you need to call that like this to avoid the warning:

Call MySub(Int2(I2 - 1))

Surely the compiler could figure that out?

*deleted duplicate post*

Explicit interface would be preferable if you are going to pass an expression where integer(2) is expected.

Explicit interface would be preferable if you are going to pass an expression where integer(2) is expected.

Yeah, old code is old but, (unfortunately sometimes!) old code still works...mostly.

Quote:

why is an (Int2 - 1) not an Int2? I know integers have a default kind but surely it is safer in this instance to assume the smallest kind is meant?...

Call MySub(Int2(I2 - 1))

Surely the compiler could figure that out?

The constant 1 (or -1) is a default integer constant. Default integers are not 16-bit integers in any current compiler. Most probably, the integer constant is a signed 32-bit integer.

For a compiler to read an individual programmer's mind is not safe, nor are compilers smart enough to do so. There is a reason why we have the Fortran Standard, and compilers are expected to conform to the standard.

In Fortran, an expression has a type, and there are rules for treating mixed-type expressions. Try this short program to understand the conflicts and concepts involved. Try to guess the answer before you run the program and see the output.

program mismatch
implicit none
integer*2 :: i2
integer, parameter :: b2=kind(i2)
write(*,*)kind(i2+131),kind(i2+131_b2)
end program mismatch

Not to discredit or contradict previous posts, I face exactly this situation quite frequently, and here is my explanation:

The argument has two parts, variable i2 and constant 1. The variable is integer(2) and the constant is integer(4).  When the compiler forms the sum i2-1, the i2 is promoted to integer(4) to match the constant, with the result (i2 - 1) is integer(4).

I usually fix this by specifying (i2 - 1_2), where ?_2 is a shorthand way of writing int2(?).

Don't know if this is highly recommended by Intel but it is easiest for me.  

_2 is a kind suffix - in the language, it is a way to specify that a constant is of the specified kind. You can have a kind number (2) or a PARAMETER constant with the appropriate value.

int2 is an extension - int(?,2) is the standard way of writing this. It means convert the argument (? here) to an integer(2).

I am partial to standard-conforming syntax. I will note that int (or int2) can be used for any expression, not just a literal constant.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today