- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
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?
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Note that relatively few compilers, even among those which support Cray pointers, support pointers to procedures. Certainly Cray never did. We do support this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Thank you for moderating this and thank you for all the helpful feedback and comments.
It really generates a very positive impression.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.

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