在混合的Fortran / C ++解决方案中可以安全地忽略LNK4006警告吗?

时间:2016-04-28 14:42:54

标签: c++ visual-studio linker fortran

我们当前的解决方案是Visual Studio 2013中的混合C ++ Fortran应用程序,每个应用程序大约有40个项目。

虽然我们可以很好地构建解决方案,但我们会收到大约6000个警告 - 其中绝大多数都是LNK4006警告,其中一个功能正在被重复":

warning LNK4006: _XXXXXXXXXXX@8 already defined in project1.lib(module1.obj); second definition ignored project2.lib(module1.obj)   

常见的线程是复制的函数是在Fortran模块中定义的 - 其中许多只是C ++函数的接口:

MODULE mINTERFACES

USE ISO_C_BINDING

INTERFACE
    INTEGER(4) FUNCTION GetLastErrorCode [C, ALIAS: '_GetLastErrorCode'] (index)

        USE ISO_C_BINDING

        INTEGER(C_SIZE_T), INTENT(IN) :: index
    END FUNCTION GetLastErrorCode
END INTERFACE

END

由于这些模块用于许多Fortran项目,因此每个项目都有一个独立的接口函数版本 - 因此重复。

这一切都很有道理,但我的问题是:我可以忽略警告(即在项目配置中排除它们)吗?我无法看到任何明显的方法来重构我们的代码以删除警告,我的印象是将这些接口放在模块中是一种很好的做法......

1 个答案:

答案 0 :(得分:1)

感谢所有那些在这个主题中建设性地发表评论的人 - 还感谢在https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/628995帮助英特尔论坛帖子的@IanH和Steve Lionel。

简而言之

(这是我自己的判断,没有其他人的)在这种特殊情况下,警告 是多余的但是如果你禁用它们你会错过任何可能很重要的新警告。恕我直言,这意味着你不应该禁用警告。

长答案

警告来自两个来源:

  1. 一项惯例已经成长为使用模块来包含“全局”数据,但要通过“访问器功能”来访问它,这些功能在与模块相同的文件中定义。这意味着当模块包含在许多不同的项目中时,访问器功能被多次编译。
  2. 其中一些模块包含C接口块(这是一种很好的做法),但对于返回字符串的函数,如Creating a FORTRAN interface to a C function that returns a char*中所述使用范例。虽然接口块本身没有引发重复警告,但是将C指针转换为Fortran字符串的辅助函数确实存在。
  3. 解决方案可能是将所有这些访问器函数和辅助接口例程提取到单独的文件中,并且只编译一次,但这可能需要数周时间。

    感谢@IanH,他指出你可以通过在一个单独的项目中定义所有模块来避免这种情况,然后(在Visual Studio中)只是将所有项目都设置为依赖于这个新的“共享模块” project(使用Build Dependencies - > Project Dependencies)。这现在编译没有警告; VS的“整个解决方案”搜索现在只能查找每个例程;它可能编译速度更快!总而言之,一场胜利。