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

Type aliasing

artblanchard
Beginner
471 Views
I have been working with some old F77 code written by someone else. They use Portland Group's compilers, but I'm using Intel FORTRAN for Linux (of course, that's why I'm here). It's government code, so there's no one around now who's willing to undergo a major edit.
I'm not the strongest FORTRAN developer, so here goes my problem:

program myprogram
integer x(50)
real y(50)
int nvals = 50
do 20 i=1, nvals
x(i) = 4
20 continue

copyarray(nvals, x, y)
end
--------------------------------------
subroutine copyarray(n, a, b)
integer n,a(*),b(*)
if (n.lt.0) then
do 20 i=1,-n
b(i) = a(1)
20 continue
else
do 50 i=1,n
b(i) = a(i)
50 continue
endif
return
end

The data sizes are both 4 bytes.
On return from copyarray in debug, I observe that y is in underflow, compiling with -fpe0 gives me the exception. Most of the compiler options are defaults.
Is there a way to alias the real and the integer so that this copy will be correct, or is this code not correct for the FORTRAN standard?

0 Kudos
8 Replies
TimP
Honored Contributor III
471 Views

The program doesn't comply with Fortran standard, but it appears to be working as you should expect. Typical integer value bit patterns will be seen as subnormal values when taken as floating point numbers.

You have prevented any conversion of data type. That is generally intended when people use this kind of code.

0 Kudos
Steven_L_Intel1
Employee
471 Views

The program is doing exactly what you asked of it, but that may not be what you want. You are moving the bit representation for an integer 4 (hex 00000004) to a real value. That bit representation, interpreted as a single precision floating point, is an IEEE denormalized value, hence the error.

What do you want to happen?

And yes, the code violates the Fortran standard because the arguments in the call to copyarray don't match the types of the arguments of the actual routine. But it does work if you hide the mismatch from the compiler.

0 Kudos
artblanchard
Beginner
471 Views
Apparently, this works like we would want it to happen according the vendor. They use Portland Group compilers. Could they be tricking it or aliasing types?
What I'd like to happen?
When I try to copy an array of integers, using the routine, into an array of reals, the value is the real conversion of the integer I pass in. There are many, many type mismatches like this in this code, what I put up here is just one example. I'd like to trick the compiler to think this is OK. I have tried many of the compiler options, with no success.
My problem is that I have some legit fpe's and this stuff is keeping me from even getting there in the debugger.
Thanks, Steve
0 Kudos
Steven_L_Intel1
Employee
471 Views

I think you misunderstand what this code does on the PGI compiler. I can't imagine it would do anything different in any compiler no matter what options. I often see code like this that tries to store values of arbitrary types in an integer array and then "retrieves" it later. (Don't even think of using a REAL array for this, though, as you'll find some values change when you store them!)

If all you want to do is have array y contain 50 elements of 4.0, all you need is this:

y = x

no calls, no loops.

0 Kudos
jimdempseyatthecove
Honored Contributor III
471 Views

Art,

I think your lack of understanding of what the original authorshad intended for calls to COPYARRAY. This subroutine was never written to perform data conversion. However, note thatif you call the subroutine with two arrays of REAL where REAL and INTEGER are the same size that the copy operation will work. On the older computers (and compilers) copying of integer*4 was faster than copying of real*4. I imagine you might find calls to copyarry in your code that call with two real arrays as well as calling with two integer arrays. But the old code would not call with mixed arrays nor with arrays who's element size was not that of integer (4 bytes).

If you want a conversion routine then you will have to write it using what others had suggested.

Jim Dempsey

0 Kudos
artblanchard
Beginner
471 Views
Gentlemen,
Thanks for you replies. Just so you know, I'm a C/C++/Java guy, and I've done a bit of FORTRAN. Jim, I completely understand what is going on here, just thought there was some old F77 legacy stuff that allowed this to be OK. It would be wrong in any other language. After all, if this code (which, I reiterate, is not mine, nor is it really mine to edit significantly) has withstood the test of time, why has this not been caught before? It is delivered as source, and I'm just trying to compile and run it. My guess is that someone wrote the original subroutine, someone else called it incorrectly, and the mismatch is not caught in the compile or runtime, unless I "-fpe0".

The problem is that the example I give is only one simple example of a rampant issue with this code. There is just so much of it, and limited resources to fix the problems. Neither the original developers, nor I are paid to make significant changes, and my supervision just says "make it work."
0 Kudos
Steven_L_Intel1
Employee
471 Views

I'm not sure what you mean by "caught". Most Fortran compilers would not diagnose this error by default - some can do so optionally, including Intel's. However, I don't think it is an "error" and that the routine is performing as expected,. Whatever problem you're having in the application is somewhere else.

You gave us a small example, which is great, but it does not illustrate the actual problem, whatever it is. As I wrote earlier, code like this was very popular in Fortran programs and it has a specific purpose. You need to look elsewhere for the real problem.

Perhaps it would help if you'd explain what goes wrong in the actual application.

0 Kudos
jimdempseyatthecove
Honored Contributor III
471 Views

Art,

Be careful of "fixing" someone else's code. You might end up breaking it.

If the program is producing correct results then it is possible that if the programmer lied once about the data type, he (she) may have lied twice. That is to say the lie about calling the copy subroutine with an integer array and a real array may have been from a subroutine that itself was lied about as to if the arguments were real or integer and the code worked regardless of the inconsistencies of the arguments. Introducing a conversion copy routinemay be syntacticly correct but will produce incorrect results. Examine the code carefully before you make it "read" correctly.

Being an old C/C++ programmer you must be familiar with using memcpy on structures. memcpy didn't give a hoot about the nature of the data but it did permit copying overlapping buffers. Your copy function did the same provided you called with the indicator (-N) to copy in reverse (right to left)

Jim Dempsey

0 Kudos
Reply