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

Submodules generate LNK2005 error

avinashs
New Contributor I
463 Views

I have a parent module M that is extended in two submodules A and B. However, compilation generates the error: error LNK2005: _M already defined in submodule_B.obj. Please advise as the documentation on submodules is very limited.

The full code is as below and organized in three files.

FILE 1

module M

  interface

     module subroutine A1()
     end subroutine A1

     module subroutine A2()
     end subroutine A2

     module subroutine B1()
     end subroutine B1

     module subroutine B2()
     end subroutine B2

  end interface

contains

  subroutine C()
    call A1()
    call A2()
    call B1()
    call B2()
    read *
  end subroutine C

end module M

FILE 2

submodule (M) A

contains

  module subroutine A1()
    print *, 'In A1'
  end subroutine A1

  module subroutine A2()
    print *, 'In A2'
  end subroutine A2
 
end submodule A

FILE 3

submodule (M) B

contains

  module subroutine B1()
    print *, 'In B1'
  end subroutine B1

  module subroutine B2()
    print *, 'In B2'
  end subroutine B2
 
end submodule B

0 Kudos
8 Replies
IanH
Honored Contributor II
463 Views

Which version of the compiler are you using?

How are you compiling and linking?

It "works for me" with the current release (16.0.3.207) at the command line.

0 Kudos
andrew_4619
Honored Contributor II
463 Views

I wouldn't recommend trying to use Submodules with anything other than the latest compiler. (16 update 3) as it is a new feature and there have been a number of problems.

On a separate note I can't see any advantage/point in having a contains section in the parent module. Any thoughts?

0 Kudos
avinashs
New Contributor I
463 Views

ianh wrote:

Which version of the compiler are you using?

How are you compiling and linking?

It "works for me" with the current release (16.0.3.207) at the command line.

@IanH: I am using 2016.3.207 through MS Visual Studio Community Edition 2015. I have had success with submodules as long as there is one level of dependency i.e. in my example, only submodule A is present. I did some experimenting with the settings and I found that I was using a calling convention of /iface:cvf. Changing the calling convention to default for this example eliminates the link error and the program runs fine. The problem is that my main project for which the submodule is being developed only works with the /iface:cvf calling convention.

0 Kudos
andrew_4619
Honored Contributor II
463 Views

I suspect this maybe related to https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/610575 which at the end of the day is a name decoration calling convention issue.

 

0 Kudos
Steven_L_Intel1
Employee
463 Views

No, this is a different problem peculiar to using STDCALL. I have a pretty good idea why this happens, but it's a bug. I will report it to the developers.

0 Kudos
Steven_L_Intel1
Employee
463 Views

Escalated as issue DPD200412052. I was hoping this could be worked around by adding !DEC$ ATTRIBUTES CVF to each of the procedures (has to be done in the module and the submodule) but that triggers a different bug that I will report separately.

For now you will have to avoid submodules when using CVF interfaces.

0 Kudos
Steven_L_Intel1
Employee
463 Views

Andrew was in fact right - this is related to one of the issues in that other thread. But unlike there, MODULE PROCEDURE is not a workaround using ATTRIBUTES CVF. However, the following DOES work:

In the parent module interfaces, use:

!DEC$ ATTRIBUTES STDCALL,REFERENCE,DECORATE,ALIAS:"A1" :: A1

Where A1 is replaced with the actual routine name.

Then in the submodules, don't repeat the subroutine or function but use MODULE PROCEDURE instead. For example:

submodule (M) A

contains

  module procedure A1
    print *, 'In A1'
  end procedure A1

  module procedure A2
    print *, 'In A2'
  end procedure A2
 
end submodule A

This works. 

0 Kudos
avinashs
New Contributor I
463 Views

Thank-you everyone for your insight and help. I have had success with submodules with the /iface:cvf option. However, in all those cases there was only level of dependency. To be clear, the code above would have module M and submodule A with M as its ancestor but no submodule B. I checked this variant of the test example and it works with both the default and /iface:cvf options. It is only when a second submodule B also with M as its ancestor is added that the error occurs with /iface:cvf option. The default option works well in both cases.

Just a side-note for all those who use Emacs 24.4.1 as an editor ... The automatic indenting option in Emacs does not work correctly with submodules and associate constructs. It adds/changes the "end" constructs in a manner that generates other compiler errors so please watch out for that when using submodules.

0 Kudos
Reply