【问题标题】:Legacy Fortran Code Compiling Problems旧版 Fortran 代码编译问题
【发布时间】:2015-02-15 03:15:30
【问题描述】:

我需要能够编译从 60 年代到 90 年代的旧 Fortran 代码。

代码按照编写的方式运行,即使它使用了一些不再标准的旧做法。 它在 Intel Visual Fortran 2011 编译器和 Visual Studio 2008 上成功构建。我现在在 Visual Studio 2012 和 Intel Visual Fortran 2013 上。我似乎找不到合适的选项来翻转以允许它构建。

主要问题是使用了巨大的等价数组,并且通常不是传递数组或实际指针到子例程,而是传递指针等价数组的单个值,并且以某种方式暗示使用一系列值.主要错误是

  • 实际参数的类型与虚拟参数的类型不同
  • 如果实际参数是标量,则虚拟参数应为标量,除非实际参数是字符类型或不是假定形状、指针或多态的数组元素

再一次。我知道代码确实可以正常工作。任何有用的建议将不胜感激。

【问题讨论】:

  • 我知道一个航空航天设备正在通过将 Fortran 转换为 C 来解决这个问题。事实证明,如果没有 Microsoft 的兼容编译器支持,Fortran 很难维护。
  • 我的意思是我知道我可以重写代码...
  • Fortran 编译器供应商知道向后兼容性对他们的客户很重要。我建议在 Intel Visual Fortran Compiler for Windows 论坛上提问,并提及用于处理您的代码的编译器选项。他们可能会为您提供适用于 IVF 2013 的编译器选项。如果没有,他们甚至可能会将您的问题视为错误并修复编译器。
  • 您联系过您的技术支持吗? Intel Visual Fortran 是一种商业产品,许可证附带支持。联系 Premier 支持或支持论坛software.intel.com/en-us/forums/…
  • 那些错误是您的代码被编译时警告和检查选项检测到。如果您关闭这些选项,通常不会(也无法)检测到这些错误。根据编译器识别的具体内容,您问题中的短语“不再标准”可能应该写成“never 标准”。

标签: visual-studio-2012 fortran intel-fortran


【解决方案1】:

我的特定问题的答案是转到项目属性 -> 诊断 -> 语言使用警告 -> 检查例程接口并将其设置为“否”。

【讨论】:

    【解决方案2】:

    距您的查询大约 1 年,但我刚刚遇到了一个类似的问题,涉及到我能够修复的 fortran 指针和动态内存分配。

    一个关键问题是遗留代码中的内存地址位置值等同于 INTEGER*4 数据类型,而在新操作系统中它们是 INTEGER*8。动态内存分配的工作方式是将虚拟数组“HEAP(ii)”的位置用作锚点,相对于“malloc”给出的绝对地址可以被引用。如果 HEAP 基地址(即 LOC(HEAP(1)) 为 11111,并且如果“malloc”释放的绝对地址位于内存地址 1731111111111111,并且如果 HEAP 已分配为整数 *4(或等效为实数 *4) ,那么由“malloc”释放的第一个位置等价于 HEAP((1731111111111111-11111)/4 + 1)。使用 HEAP(iaddress) 作为子例程调用中的参数,在这些异常大的索引值处使用 iaddress 允许HEAP 将用作被调用子例程中的数组参数。

    有问题的地方包括:

    POINT1.) 由“malloc”给出的已释放内存的绝对地址值已存储在 HEAP() 中存储的计算数据值之后的某个位置。该地址值存储在那里,以便以后可以使用它来释放内存。如果这个 INTEGER*8 地址被存储在新操作系统/编译器的 INTEGER*8 地址寄存器的边界上,当你试图访问这个存储的 INTEGER*8 内存地址值时,它会给出“DOOM 的十六进制”类型的崩溃基于 INTEGER*4 HEAP 的索引。这可以通过在内存地址的存储值的存储点之前包含一个额外的 1 INTEGER*4 位置的填充来避免。每当前一个数据段中存储的数据值的数量是奇数个 XXXX*4 数据值时,都需要这样做。存储的内存地址值可以在需要时读取为 INTEGER*8 地址,方法是将 INTEGER*4 HEAP() 等效为 INTEGER*8 LONGHEAP() 并在 longheap() 中使用大约为 1 的索引值/2 用作 HEAP() 中的数组索引的超长索引值(使用 -1 和 +1 来说明从 1 开始的数组的 fortran 索引)

    POINT2.) 需要跟踪存储内存地址位置的所有变量并将其从 INTEGER*4 切换到 INTEGER*8。这在调用函数的子例程中很棘手......要寻找的一种构造是内存位置的交换,TEMP = Iaddress; Iaddress = Jaddress; Jaddress = TEMP:在此类交换中,确保 TEMP 为 INTEGER*8。其他内存地址算术和临时存储变量也可能导致问题。此外,一旦您进行了此切换,您需要检查这些新的 INTEGER*8 变量是否已用作子程序和函数调用中的参数。如果是这样,您需要适当地修改被调用的函数/子例程,并确保数据类型在对同一函数/子例程的所有其他调用中保持一致。

    可能只是将所有内容切换到 *8 并检查涉及索引算法的语句,但我不确定逻辑 *8 值的新数组和旧整数 * 的一些花哨的东西是否2 个数组就可以了。

    【讨论】:

    • 您应该能够更改整数的默认类型值,这可能对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多