2014-01-30 14 views
2

我有一个共享库子程序:传递的数组与更多的元素预计在子程序

SUBROUTINE DLLSUBR(ARR) 
    IMPLICIT NONE 
    INTEGER, PARAMETER :: N = 2 
    REAL ARR(0:N) 
    arr(0) = 0 
    arr(1) = 1 
    arr(2) = 2 
END 

而假设我会叫它从可执行:

REAL ARR(0:3) 
CALL DLLSUBR(ARR) 

注:该代码在Debug + /check:all选项打开时没有任何警告或错误,编译并运行(DLLSUBR位于模块内部)。

这可能导致内存损坏或一些奇怪的行为?在哪里可以找到有关在Fortran规范中传递具有不同大小的数组的信息?

+0

看到我的编辑更详细的解释。 –

回答

3

如果您将伪参数元素计数为较小或相等,它实际上允许通过序列关联规则显式形状数组。当子程序需要更多元素时,它是被禁止的。

显式形状数组通常需要参数通过副本传递。当编译器无法证明数组是连续的时(指针或假定的形状数组伪参数),会发生这种情况。如果传递的元素数量较少,则该子例程可以在数组部分的副本之后访问一些垃圾。

在你的情况下,一切都会好的,因为你传递给子程序的次数会减少。

2008的Fortran 12.5.2.11.4:

4表示元素序列和 对应于是阵列的伪参数的实际参数与所述伪参数,如果伪参数相关序列 是明确形状或假定大小的数组。实际 参数的排名和形状不需要与伪参数的排名和形状 一致,但伪参数中元素的数量不得超过实际参数的元素序列中元素的数量 。如果 伪参数为假设大小,则伪参数中元素的数量恰好是元素 序列中元素的数量。

+0

如果它是共享库,它需要导出以便能够链接它(与另一端的语言无关) – Peter

+0

它也是如何打破标准,你能指点我的链接/部分吗?编译器可以检查API,但我想知道更多关于ABI更改的信息(在我的示例中,API保持不变) – Peter

+0

广告评论1)是的,但在正常的操作系统上,您不关心这些指令,因为它是自动完成的。我必须找出它在Windows上的作用。另外,当我在Windows上使用gfortran进行一些'bind(C)'回调函数时,我从来不需要这样做,它只是工作。 –