- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First of all I have to say that I'm not an expert fortran programer.. and my english is not very good.
I'm porting a Linux fortran program to Windows, and I'm using Compaq Visual Fortran 6.6a for that task (later I will try to migrate the project to Intel Visual Fortran).
The program compiles and links in Linux perfectly, with ifort.
But when I compile with CVF I get several link errors, for example, this:
input1.obj : error LNK2001: unresolved external symbol _SETUP@52
It seems that the problem is to call a subroutine with different argument types.
Subroutine SETUP is defined in this mmaner:
SUBROUTINE SETUP(IARRAY,CARRAY,ICHANT,BOWMX,BOWMY,BOWMSR, BOWZ, IRMX, LF, NPCR, LDET, DETMP, NFTA)
INTEGER IARRAY(IRMX,IRMX)
CHARACTER*8 CARRAY(IRMX,IRMX)
INTEGER ICHANT(ID,JD)
REAL BOWMX(IAFULL*IAFULL)
REAL BOWMY(IAFULL*IAFULL)
etc..etc
But it's called in this form:
CALL SETUP(A(LPARAY),A(LPNCCR),A(LPBCHA),A(LPBOWX),A(LPBOWY), & A(LPBOWM),A(LPBOWZ),IRMX, A(LPLF), A(LPNPCR), & A(LPLDET),A(LPDETM),A(LPNFTA))
Where A is a big array of REALs:
PARAMETER (ICLDIM=35000000)
COMMON ARRAY/ A
REAL A(ICLDIM)
Why this is ok in linux with ifort and not valid in CVF?
My only idea to resolve the problem is to create some EQUIVALENCE variables to match the argument types and use then during the call, but I think that must be a more elegant solution, since I get this mistake in more subroutines.
Any sugestion will be very apreciated.
Kind regards,
Marcos.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With the linux compiler, there's no argument consistency check unless you use explicit interfaces or ask for an automatic version of it (-gen-interfaces).
If, you want to hide the violations from CVF, you can split the source file and compile the subroutines separately, but there's a good change of trouble at run time.
Fortran standard doesn't allow EQUIVALENCE between CHARACTER and numerical data types, although CVF may accept it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
nharcor: CVF uses (by default) the STDCALL name decoration, and when a dummy argument is a character type variable, an extra length argument is expected to be passed on the stack by the caller, and this extra argument is used in calculating the @nn suffix. In your caller, instead of a character argument you have a real type, so the caller causes the suffix to be @52, whereas the subroutine gets a suffix of @56.
You may consider using the /iface:cref option of the CVF compiler. Using this option will make the @nn mismatch go away, but may well create other problems.However, if the code is working correctly on Linux it may well do the same with this option of CVF.
A more permanent but time-consuming solution would be to have not one but two memory pools in blank common, one for numeric variables and one for character variables. If you choose this route, you will have to redo the subscript/offset calculations in the places in your code where the memory pools are parcelled out. Prior to doing all that you may well consider using dynamic array allocation instead.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A lot of thanks for your explanations.
I understand now what is the problem with the @nn numbers and why the linker fails.
I try with the "/iface:cref" option and this really elimitantes the link errors.... but unfortunately have catastrophic effects and the program fails.
At the end I solve the problem using EQUIVALENCE statements so I always pass the correct types, but this involved a lot of file changes and I see this solution a little dirty. Butt at least it runs ok!!
The program in fact uses dinamic array allocation by means of a module like this:
module Global_a
! This code is active only if f90 dynamic memory is being used
implicit none
save
integer, parameter :: icldim=35000000 ! default size of container
integer :: icldim_used
integer :: icldim_input
integer :: icldim_restart
real, allocatable, dimension (:) :: a
end module Global_a
But I have replaced the module with a include file and use static memory.
I did that becouse I don't know how to use EQUIVALENCE with an allocatable array. So I changed all the code to static memory. Of course, again, this is a dirty solution becouse make the executable very big.
Any of you know hoy tu use EQUIVALENCE with dinamic memory so I can map and shape the array to diferent types?
Any way, a lot of thanks.
Kind regards,
Nharkor.
I have tryed the

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page