强制显式变量声明与gfortran

问题描述:

我正在使用mex链接一些fortran代码(f90)从matlab,我偶尔有matlab冻结。强制显式变量声明与gfortran

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

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

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

问题:

  1. 我怎么gfortran需要在编译时明确声明的所有变量?如果没有,有没有办法至少得到警告?

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

  3. 有没有办法强迫gfortran将“真实”数据类型解释为特定类型,比如说“真实* 4”?

  4. 有什么想法让fortran代码在从matlab中的mex编译例程中调用时冻结(数据类型不匹配除外)?

感谢您的任何帮助。

直到我明白了这一点,我会经历许多代码行,试图列出所有隐式定义的变量。 不用说,我将大大感激的人谁解放了我从这么无聊的任务......

最佳,

G.

  1. 您可以要求通过添加implicit none明确声明所有变量。
  2. 我相信默认的“真实”数据类型是real*4
  3. 您可以使用命令行标志,-fdefault-real-8迫使声明为real所有变量被解释为real*8

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

+0

非常感谢,特别是关于-fdefault-real-8标志的提示。你知道是否还有一个-fdefault-real-4标志吗?我在gfortran上尝试过,但它似乎没有工作...... – gvrocha 2010-08-24 19:40:13

+0

我不这么认为,因为那只是默认设置。 – 2010-08-24 19:52:09

+0

所以真正的默认值不是架构依赖呢? – gvrocha 2010-08-24 19:57:49

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

implicit none 

implicit undefined(a-z) 

Real是架构相关的;默认大小通常可以通过命令行选项进行修改。

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

+0

感谢您的快速回复。 – gvrocha 2010-08-24 19:40:28

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

使用gfortran,您可以使用编译器选项-fimplicit-none。这个好处是,它会捕获你忘记明确键入的变量,即使你忘记了包含隐含的没有。其他大多数编译器都有类似的选项。

这两个都是强烈推荐 - 隐式类型是有害的,并允许错字错误创建意想不到的变量。

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

+0

非常感谢,特别是针对-fimplicit-none标志 – gvrocha 2010-08-24 19:39:27

+0

+1的提示,尤其是对于编译器选项。 – Wildcat 2010-08-24 20:38:15

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

让我们来谈谈浮点运算。问题在于(MATLAB提到的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)。那么,它可以冻结该程序。

+1

观察>>猜测 - 非常好。 – 2010-08-24 20:39:25

+2

技术上,selected_real_kind(7,38)提供至少7位精度 - 如果编译器选择它可以提供更多精度,所以这不能保证选择IEEE类型。如果您绝对必须拥有IEEE类型,则有Fortran 2003的新IEEE模块 - 但尚未普遍支持。 – 2010-08-24 20:59:41

+0

@ M. S. B .:您的评论完全有效。这个想法是让Fortran代码中的浮点数的精度至少达到IEEE的单精度和双精度。 – Wildcat 2010-08-25 07:38:39