我们试图在 C++ 中接管旧版 Fortran 代码(+100,000 行代码)的内存分配,因为我们使用 C 库在集群上分区和分配分布式内存。可分配的变量在模块中定义。当我们调用使用这些模块的子例程时,索引似乎是错误的(移动了一位)。然而,如果我们将相同的参数传递给另一个子例程,我们就会得到我们所期望的结果。下面的简单例子说明了这个问题:
你好.f95:
MODULE MYMOD
IMPLICIT NONE
INTEGER, ALLOCATABLE, DIMENSION(:) :: A
SAVE
END MODULE
SUBROUTINE TEST(A)
IMPLICIT NONE
INTEGER A(*)
PRINT *,"A(1): ",A(1)
PRINT *,"A(2): ",A(2)
END
SUBROUTINE HELLO()
USE MYMOD
IMPLICIT NONE
PRINT *,"A(1): ",A(1)
PRINT *,"A(2): ",A(2)
CALL TEST(A)
end SUBROUTINE HELLO
main.cpp
extern "C" int* __mymod_MOD_a; // Name depends on compiler
extern "C" void hello_(); // Name depends on compiler
int main(int args, char** argv)
{
__mymod_MOD_a = new int[10];
for(int i=0; i<10; ++i) __mymod_MOD_a[i] = i;
hello_();
return 0;
}
我们正在编译:
gfortran -c hello.f95; c++ -c main.cpp; c++ main.o hello.o -o main -lgfortran;
运行 ./main 的输出是
A(1): 1
A(2): 2
A(1): 0
A(2): 1
正如您所看到的,尽管两个子例程都打印了 A(1) 和 A(2),但 A 的输出是不同的。因此,看起来 HELLO 是从 A(0) 开始的,而不是从 A(1) 开始的。这可能是因为 ALLOCATE 从未在 Fortran 中直接调用过,因此它不知道 A 的边界。有什么解决方法吗?