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

passing INTEGER(4) argument to INTEGER(2) dummy

forall
Beginner
505 Views
Is there a danger in doing so (other than reduction in the range of values handled)?

I am linking to a 3rd party legacy routine in a static library (I know, not a very nice situation), and am not always sure what type of integers it expects (from a scant documentation some args are INTEGER(2) others INTEGER(4), etc).

It does not complain at compile/build time regardless of what integers I pass (is this normal?). It seems to execute correctly (no runtime error).

Is there any danger in always passing integer(4)'s to such routines? I am happy to get integer overflows if I happen to pass a value outside the INT(2) range, but would rather not risk the danger of actually getting wrong results with no indication.

thanks in advance!
0 Kudos
2 Replies
jimdempseyatthecove
Honored Contributor III
505 Views

Unless explicitly stated, the integer variables are passed by reference. Calling with integer(4) will not present a situation were the routine clobbers unintended data. From that respect you would be OK. The problem would come when the routine called intends to return a negative result. In this case, you would see a largish positive number (.ge. 32768). And your code may then break.

If the API is documented as to which to use, and if you wish to avoid looking at the documentation each time you make a call, then I suggest writing an INTERFACE declaration (place into a header or better a module). Then you cannot make a mistake (without error or warning).

Jim Dempsey
0 Kudos
jparsly1
New Contributor I
505 Views
For data going into a routine, a combination of "pass by reference" and the right sort of endianness will sometimes
allow this to work. On a "little endian" architecture (like a PC, for example) an integer is stored with its least significant byte 1st. For example, the 4 byte integer 4 shows up in memory as 04 00 00 00. The 2 byte version
would be 04 00. Note that in this case the first 2 bytes of the 4 byte integer are the same as the 2 byte version.
When you pass the integer 4 to a subroutine "by reference" the subroutine is sent the address where the integer is
stored (even if you pass a constant; the constant will be stored somewhere in memory and the address will be sent). If the routine wants a 2 byte integer, it will grab the first two bytes at the address that it is given, which
works just fine even if a 4 byte integer was used in the argument list.

For data coming back, it might not work so well. If the subroutine was expecting a 2 byte integer, it will only replace 2 of the 4 bytes in the 4 byte integer whose address was passed. The result that you get will depend on what
value the 4 byte integer had going into the routine. For example if the 4 byte integer was negative, and the
results coming back is supposed to be positive, you won't get the right result. Similarly if the 4 byte integer had
a positive value > 2**16-1 going in, there will be problems. The safest case for this to work is where you know that
the results will always be positive. If you initialize your 4 byte integer to 0 before it is used, it should be ok.

This also will not be a good thing if you try it the other way. Passing a 2 byte integer into a routine expecting
a 4 byte integer is a recipe for disaster.


Anyhow, its possible for this to work, given exactly the right combination of argument passing scheme and
architecture. But its not portable, and could come back to bite you sometime in the future. Make sure you
write down what is going on, right there in the code somewhere, and acknowledge the risk.


0 Kudos
Reply