使用gfortran强制显式变量声明

时间:2010-08-24 18:47:41

标签: types fortran mex gfortran fortran90

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

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

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

为了排除数据类型不匹配作为冻结的原因,我想让编译器要求显式声明所有变量。

问题:

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

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

  3. 无论如何迫使gfortran将“真实”数据类型解释为特定种类,比如说“真正的* 4”?

  4. 关于在matlab中使用mex编译例程调用fortran代码时的任何想法(数据类型不匹配)?

  5. 感谢您的帮助。

    直到我弄清楚这一点,我将尝试列出所有隐含定义的变量的许多代码行。 毋庸置疑,我将非常感谢任何让我摆脱这种无聊任务的人......

    最佳,

    -G。

4 个答案:

答案 0 :(得分:2)

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

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

两者都是强烈推荐的 - 隐式输入是有害的,并允许打字错误创建意外变量的错误。

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

答案 1 :(得分:2)

已经提到了

IMPLICIT NONE和编译器选项。

我们来谈谈浮点运算。问题是(ss提到here)MATLAB根据IEEE® Standard 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标准单精度浮点类型。

所以它可能是错误的根源。精度在某处丢失,某些变量等于0.0而不是稍微大于/小于0.0,然后除以该值(正好为0.0)。好吧,它可以冻结程序。

答案 2 :(得分:1)

  1. 您可以通过添加implicit none来明确声明所有变量。
  2. 我认为默认的“真实”数据类型是real*4
  3. 您可以使用命令行标记-fdefault-real-8强制声明为real的所有变量都被解释为real*8
  4. 注意(编写更多代码,不一定要尝试解决当前的错误): 如果您使用的是Fortran 90代码,则可以使用real(kind=4)real(kind=8)使用gfortran,而不是real*4real*8语法。我已经远离使用命令行标志设置实际或整数大小,而是使用integer, parameter :: REAL_SIZE变量来保存适当的数字(我通常选择4或8,因为我使用的所有编译器都支持它们,但是如果你想要非常便携,你应该使用selected_real_kind例程)

答案 3 :(得分:0)

其中一个适用于大多数编译器,因为Fortran 77:

implicit none

implicit undefined(a-z)

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

我没有任何与Matlab联系的经验。