遗留Fortran代码编译问题

时间:2014-12-16 17:55:35

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

我有遗留的Fortran代码,范围从60年代到90年代,我需要能够编译。

代码按照编写的方式工作,即使它使用了一些不再标准的旧实践。 它是在英特尔Visual Fortran 2011编译器和Visual Studio 2008上成功构建的。我现在使用的是Visual Studio 2012和英特尔Visual Fortran 2013.我似乎找不到合适的选项来翻转以允许它构建。

主要的问题是使用了巨大的等价数组,并且通常不是将数组或实际指针传递给子例程,而是只传递指针等价数组的单个值,并且暗示它使用一系列值。主要错误是

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

It is about 1 year since your query, but I just had a similar problem that involved fortran pointers and dynamic memory allocations that I was able to fix.

A key problem was that memory address location values in the legacy code were equivalent to INTEGER*4 datatype whereas in the new operating system they were INTEGER*8. The way dynamic memory allocation worked was that the location of a dummy array 'HEAP(ii)' was used as an anchor point, relative to which the absolute address given by "malloc" could be referenced. If HEAP base address (i.e. LOC(HEAP(1)) was 11111, and if the absolute address freed by "malloc" was at memory address 1731111111111111, and if HEAP had been assigned to be integer*4 (or equivalently real*4), then the first location freed by "malloc" was equivalent to HEAP( (1731111111111111-11111)/4 + 1). Using HEAP(iaddress) as an argument in subroutine calls with iaddress at these insanely large index values allowed the appropriate portions of HEAP to be used as the array argument in the called subroutine.

Places with problems included:

POINT1.) The value of the absolute address of freed memory, as given by "malloc", had been stored at a position in HEAP() just after the stored calculation-data values. This address value was stored there so that it could be used later to free memory. If this INTEGER*8 address was stored across the boundaries of INTEGER*8 address registers for the new operating system/compiler, it would give a "HEXADECIMALS of DOOM" style crash, when you tried to access this stored INTEGER*8 memory address value based on the index of INTEGER*4 HEAP. This could be avoided by including an extra padding of 1 INTEGER*4 location before the storage spot for this stored value of the memory address. This was needed whenever the number of stored data values in the preceding data segment was an odd number of XXXX*4 data values. The stored memory address value could be read as an INTEGER*8 address, when it was needed, by EQUIVALENCE-ing INTEGER*4 HEAP() to INTEGER*8 LONGHEAP() and using an index value in longheap() that was about 1/2 of the insanely long index value used as the array index in HEAP() (with -1's and +1's to account for fortran indexing of arrays that starts from 1)

POINT2.) All variables that stored memory address locations needed to be tracked down and switched from INTEGER*4 to INTEGER*8. This was tricky in subroutines that called functions that called functions ... One construct to look for is the swapping of memory locations, TEMP = Iaddress; Iaddress = Jaddress; Jaddress = TEMP: in such swaps, make sure TEMP is INTEGER*8. Other memory-address arithmetic and temporary storage variables can cause problems as well. Also once you have made this switch, you need check whether these new INTEGER*8 variables have been used as arguments in calls to subroutines and functions. If so, you need to modify the called functions/subroutines appropriately and make sure that datatypes are consistent in all of the other calls to the same function/subroutine.

It might have been possible just to switch everything to *8 and check for statements involving the indexing arithmetic, but I wasn't sure if the new arrays of logical*8 values and some of the fancy stuff with the old integer*2 arrays would have worked.

相关问题