Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29282 Discussions

Link warnings about variables defined multiple times

van_der_merwe__ben
New Contributor II
966 Views
This may be a simple question for someone to answer please.

It is fairly common for Fortran files to share and link to the same variables without issuing multiple link warnings. For example, you can have the line "INTEGER XDATA" in multiple files and the all link to the same instance without any warnings.

However, it seems that if those variables are pointers or declarations of methods to ensure the correct calling convention, then you get a warning about the item being defined in more than one file.

For example, if in x1.for and x2.for you have the line:

pointer (p_urxstr, f_urxstr)

Then when you link you get this warning:

x1.obj : warning LNK4006: F_URXSTR already defined in x2.obj; second definition ignored

The same thing happens if you have code like this in multiple files (to ensure that arguments are properly handled when calling):

!DEC$ ATTRIBUTES DLLIMPORT :: xSVR
INTERFACE
SUBROUTINE xSVR(STDINr,INXXr)
INTEGER INXXr(45)
REAL STDINr(6500)
END SUBROUTINE xSVR
END INTERFACE

pointer (pServer, xsvr)
pServer = GetProcAddress (pLibrary,'xSVR'C)
call xsvr(STDIN,INXX)

Then you get a warning about xSVR being defined in multiple objs. The above code does not really define xSVR does it? It merely says there is a method being linked in from somewhere else named xSVR and this is how its arguments should be handled.

Basically what I am trying to do is clean up the warnings about items being multiply defined. Maybe when it comes to pointers or methods there is a compiler glitsch or some other way in which I need to declare them?
0 Kudos
9 Replies
TimP
Honored Contributor III
966 Views
Unfortunately, the only simple thing to say about Cray pointers is they are different from Fortran pointers, and there have been variations in past usage. I don't know if there is an expected way to use them in f90 interface blocks, as the portable way in f90 (the way documented in textbooks) is to use Fortran pointers. All Cray pointer code I have seen shares the pointers by block COMMON, which certainly is not ideal.
0 Kudos
Steven_L_Intel1
Employee
966 Views
I tried creating a compileable example based on your description and I could not reproduce the result you showed. However, I will comment that you must not use a DLLIMPORT directive on XSVR as you are calling (presumably) LoadLibrary and GetProcAddress to access the routine. DLLIMPORT is for when you want the linker to establish the association with the routine in a DLL (whose export library you link against.)

Also, if you are going to use DLLIMPORT in general, it should be inside the interface block if you have one and not outside.

Can you come up with a small but complete example that shows the multiple definition problem?
0 Kudos
Steven_L_Intel1
Employee
966 Views
Responding to Tim's comment - the use here of "Cray pointers" is fine - we allow their use for procedures and this general code is the right way to approach dynamic loading of a DLL.

Note that relatively few compilers, even among those which support Cray pointers, support pointers to procedures. Certainly Cray never did. We do support this.
0 Kudos
van_der_merwe__ben
New Contributor II
966 Views
Here is one example of this. Note that this code is a small abstract of one larger case where this happens.

Save the following to a file called x2.f90:

module X2
interface
subroutine XRtoRun(p1)
integer p1
end subroutine
end interface
pointer (p_XRtoRun,XRtoRun)
end module X2

And save the following to x1.f90:

subroutine X1S(Name)
use x2
integer p1
call XRtoRun(p1)
end subroutine X1S

Now if you compile and link them both, you get this:

ifort.exe @x.fcf HYPSQP tooptimx2.f90
ifort.exe @x.fcf HYPSQP tooptimx1.f90
Libing x.lib...
lib /OUT:"X:x.lib" x2.obj x1.obj /machine:IX86 /NODEFAULTLIB /nologo
x2.obj : warning LNK4006: XRTORUN already defined in x1.obj; second definition ignored

In case it is relevant, x.fcf contains this:

/Zi
/Od
/W1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /c
/nologo /warn:nofileopt /Qzero /Qsave /align:rec1byte
/check:bounds
/iface:mixed_str_len_arg
/include:"C:Program FilesIntelCompilerFortran9.1IA32Include"
/Fomobj32d
/module:mobj32d
/define:USINGINTELFORTRAN
0 Kudos
van_der_merwe__ben
New Contributor II
966 Views
Here is another example. Place this code in x1.for:

subroutine X1()

INTERFACE
SUBROUTINE xSVR(INXXdc)
INTEGER INXXdc(63)
END SUBROUTINE xSVR
END INTERFACE

pointer (pxSVR,xSVR)

end subroutine X1

And this code in x2.for:

SUBROUTINE X2()

INTERFACE
SUBROUTINE xSVR(INXXdc)
INTEGER INXXdc(63)
END SUBROUTINE xSVR
END INTERFACE

pointer (pxSVR,xSVR)

end subroutine X2

If you compile and then link them you get:

lib /OUT:"X:x.lib" x1.obj x2.obj /machine:IX86 /NODEFAULTLIB /nologo

x1.obj : warning LNK4006: XSVR already defined in x2.obj; second definition ignored

In theory you should be able to add another file that actually defines and implements xSVR without any warnings.

Note that this only happens if you use "pointer". If you take the pointer lines out and replace them with direct calls to xSVR then you dont get the link warning. In that case the obj files (using dumpbin) contains "013 00000000 UNDEF notype () External | _XSVR" but with the pointer declaration you get "01A 00000000 SECT4 notype External | XSVR" which is possibly wrong?


0 Kudos
Steven_L_Intel1
Employee
966 Views
Ok, I can reproduce this but only if I use /Qsave and /Qzero. I recall a similar problem in the past - I'll let the developers know about it.
0 Kudos
van_der_merwe__ben
New Contributor II
966 Views
Hi,

I am using:

Intel Fortran Compiler for 32-bit applications, Version 9.1 Build 20061103
Z Package ID: W_FC_C_9.1.033

and

Microsoft 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x8

Basically Visual Studio 2005 service pack 1 with Intel Fortran 9.1. I know 10.0 has been released but we are working on getting a release out so we cant upgrade compilers until its out the door.
0 Kudos
van_der_merwe__ben
New Contributor II
966 Views
Oh, by the way Steve Lionel,

Thank you for moderating this and thank you for all the helpful feedback and comments.
It really generates a very positive impression.
0 Kudos
Steven_L_Intel1
Employee
966 Views
Thanks for the kind words.

This bug is still in the current 10.0 compiler. It requires /Qzero and affects procedure pointees. I'd encourage you to submit a problem report to Intel Premier Support about this as that helps with priorities. If you do, please reference T78852-CP.
0 Kudos
Reply