2

我正在使用 mex 从 matlab 链接一些 fortran 代码(f90),并且我偶尔会冻结 matlab。

过去,由于数据类型之间的不匹配(例如整数 * 4 与整数 * 8),我发生了冻结。

我链接的代码有许多隐式定义的变量,所以我想知道是否存在仅偶尔发生的隐藏数据类型冲突。

为了排除数据类型不匹配是导致冻结的原因,我希望编译器要求所有变量都被显式声明。

问题:

  1. 如何让 gfortran 要求在编译时显式声明所有变量?如果做不到这一点,有没有办法至少得到警告?

  2. gfortran 是否将“真实”数据类型解释为所有体系结构中的特定类型?如果是这样,它是哪一个(真实* 4,真实* 8,...)?

  3. 无论如何强制gfortran将“真实”数据类型解释为特定类型,例如“真实* 4”?

  4. 关于从 matlab 中的 mex 编译例程调用时导致 fortran 代码冻结的任何想法(数据类型不匹配除外)?

谢谢你的帮助。

在我弄清楚这一点之前,我将通过许多行代码尝试列出所有隐式定义的变量。不用说,我将非常感谢任何让我从如此无聊的任务中解脱出来的人......

最好的,

G。

4

4 回答 4

2

如前所述,在您的源代码中,您可以使用隐式 none。优点是它可以移植到所有编译器。

使用 gfortran,您可以使用编译器选项-fimplicit-none。这个优点是即使您忘记包含隐式无,这也会捕获您忘记显式键入的变量。大多数其他编译器都有类似的选项。

强烈推荐两者 - 隐式类型是有害的,并且允许错误创建意外变量的拼写错误。

简单的“真实”意味着什么取决于编译器——如果您有特定的要求,最好使用更具体的声明。最好的方法是使用选定的真实类型内在函数定义一个参数并使用它——类似的讨论参见Fortran:integer*4 vs integer(4) vs integer(kind=4)

于 2010-08-24T19:23:16.233 回答
2

IMPLICIT NONE和已经提到的编译器选项。

让我们谈谈浮点运算。问题是(这里提到的 ss)MATLAB 根据IEEE® 标准 754构造双精度(或双精度)和单精度(或单精度)数据类型,但 Fortran 标准不需要它的默认值和双精度实数以符合本标准。如您所见,标准文档甚至使用另一个名称(默认为实数,不是单精度)。

MODULE kinds

  IMPLICIT NONE

  INTEGER, PARAMETER :: fortran_default = kind(0.0)
  INTEGER, PARAMETER :: fortran_double = kind(0.0D0)
  INTEGER, PARAMETER :: ieee_single = selected_real_kind(7, 38)
  INTEGER, PARAMETER :: ieee_double = selected_real_kind(15, 307)

END MODULE kinds

在我的种类规范的前两个字符串中,我使用了方便的方法来获取默认实数和双精度实数的种类。接下来的两种对应于提到的 IEEE 标准。

PROGRAM main

  USE kinds

  IMPLICIT NONE

  REAL(kind=ieee_single) :: is
  REAL(kind=ieee_double) :: id
  REAL(kind=fortran_default) :: fs
  REAL(kind=fortran_double) :: fd

  PRINT *, kind(is), precision(is), range(is)
  PRINT *, kind(id), precision(id), range(id)
  PRINT *, kind(fs), precision(fs), range(fs)
  PRINT *, kind(fd), precision(fd), range(fd)

END PROGRAM main 

我的机器(Mac OS X 10.6,gfortran 4.5.1)上的输出是:

   8          15         307
   8          15         307
   4           6          37
   8          15         307

所以 Fortran 的默认实数类型不等于 IEEE 标准的单精度浮点数类型。

So it might be the source of bugs. The precision is lost somewhere, some variable becomes equal to 0.0 instead of being slightly bigger/smaller the 0.0 and then you divide by this value (which is exactly 0.0). Well, it can freeze the program.

于 2010-08-24T20:36:50.337 回答
1
  1. 您可以要求通过添加显式声明所有变量implicit none
  2. 我相信默认的“真实”数据类型是real*4.
  3. 您可以使用命令行标志-fdefault-real-8强制所有声明为real的变量解释为real*8

注意(为了编写更多代码,不一定要尝试解决当前的错误):如果您使用的是 Fortran 90 代码,则可以使用real(kind=4)orreal(kind=8)与 gfortran 而不是real*4orreal*8语法。我已经不再使用命令行标志设置实数或整数大小,而是使用integer, parameter :: REAL_SIZE变量来保存适当的数字(我通常选择 4 或 8,因为我使用的所有编译器都支持它们,但如果你想成为非常便携,您应该使用selected_real_kind例程)

于 2010-08-24T18:56:16.137 回答
0

自 Fortran 77 以来,其中一种适用于大多数编译器:

implicit none

或者

implicit undefined(a-z)

Real依赖于架构;默认大小通常可以通过命令行选项修改。

我没有任何与 Matlab 链接的经验。

于 2010-08-24T18:55:55.013 回答