使用 gfortran 强制显式变量声明
我正在使用 mex 从 matlab 链接一些 fortran 代码 (f90),并且偶尔会出现 matlab 冻结的情况。
过去,由于数据类型之间不匹配(例如整数*4 与整数*8),我遇到了冻结问题。
我链接的代码有许多隐式定义的变量,所以我想知道是否存在仅偶尔发生的隐藏数据类型冲突。
为了排除数据类型不匹配导致冻结的情况,我希望编译器要求显式声明所有变量。
问题:
如何让 gfortran 要求所有变量在编译时显式声明?如果做不到这一点,有没有办法至少得到警告?
gfortran 是否将“真实”数据类型解释为所有架构中的特定类型?如果是,那么它是哪一个(real*4、real*8,...)?
是否有办法强制 gfortran 将“真实”数据类型解释为特定类型,例如“real*4”?
关于在 matlab 中从 mex 编译例程调用时使 fortran 代码冻结的任何想法(数据类型不匹配除外)?
感谢您的任何帮助。
在我弄清楚这一点之前,我将通过许多行代码来尝试列出所有隐式定义的变量。 不用说,我将非常感谢任何将我从如此无聊的任务中解放出来的人......
最好,
G。
I am linking some fortran code (f90) from matlab using mex and I am having matlab freeze occasionally.
In the past, I had freezing happening due to mismatch between data types (say integer*4 vs integer*8).
The code I am linking has many implicitly defined variables, so I am wondering if there is a hidden data type conflict that only occurs occasionally.
To rule out data type mismatch as the cause of the freeze, I would like to have the compiler requiring all variables to be explicitly declared.
Questions:
How do I get gfortran to require all variables to be explicitly declared at compile time? Failing that, is there any way to at least get warnings?
Is a "real" data type interpreted by gfortran as a specific kind in all architectures? If so, which one is it (real*4, real*8, ...)?
Is there anyway to force gfortran to interpret the "real" data type as a specific kind, say "real*4"?
Any ideas on what makes the fortran code to freeze when called from a mex compiled routine in matlab (other than data type mismatches)?
Thanks for any help.
Until I figure this out I will be going through many lines of codes trying to list all implicitly defined variables.
Needless to say, I will be tremendously grateful to anyone who frees me from such a boring task...
Best,
G.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如前所述,在源代码中,您可以使用隐式无。优点是它可以移植到所有编译器。
对于 gfortran,您可以使用编译器选项-fimplicit-none。这个优点是,即使您忘记包含隐式 None,它也会捕获您忘记显式键入的变量。大多数其他编译器都有类似的选项。
强烈推荐两者——隐式类型是有害的,并且会导致拼写错误,从而创建意外的变量。
简单的“real”的含义取决于编译器——如果您有特定的要求,最好使用更具体的声明。最好的方法是使用选定的实数内在函数定义一个参数并使用它 - 有关类似的讨论,请参阅 Fortran:整数*4 vs 整数(4) vs 整数(kind=4)
As already stated, in your source code, you can use implicit none. The advantage is that this is portable to all compilers.
With gfortran, you can use the compiler option -fimplicit-none. This advantage is that this will catch variables that you forgot to explicitly type even if you forgot to include implicit none. Most other compilers have a similar option.
Both are highly recommended -- implicit typing is pernicious, and allows the mistake of typos creating unintended variables.
What a plain "real" means is up to the compiler -- if you have specific requirements, it is best to use a more specific declaration. The best way is to define a parameter with the selected real kind intrinsic and use that -- for a similar discussion see Fortran: integer*4 vs integer(4) vs integer(kind=4)
IMPLICIT NONE
和编译器选项已经提到。我们来谈谈浮点运算。问题是(ss提到此处)MATLAB 根据 IEEE® 标准 754 但 Fortran 标准不要求其默认值和双精度实数符合此标准。正如您所看到的,标准文档甚至使用了另一个名称(默认实数,而不是单精度)。
在我的类型规范的前两个字符串中,我使用了方便的方法来获取默认实数和双精度实数的类型。接下来的两种对应于提到的 IEEE 标准。
我的机器(Mac OS X 10.6,gfortran 4.5.1)上的输出是:
所以 Fortran 的默认实数类型不等于 IEEE 标准单精度浮点类型。
所以这可能是错误的根源。精度在某处丢失,某个变量变得等于 0.0,而不是稍微大于/小于 0.0,然后除以该值(正好是 0.0)。嗯,它可以冻结程序。
IMPLICIT NONE
and compiler option already mentioned.Let's talk about floating point arithmetic. The problem is that (ss mentioned here) MATLAB constructs both the double-precision (or double) and the single-precision (or single) data types according to IEEE® Standard 754 but Fortran standard doesn't require it's default and double precision real's to conform this standard. As you can see the standard document even use another name (default real, not single-precision).
Here in the first two strings of my kinds specification I've used convenient way to obtain kinds for default real and double precision real. The next two kinds correspond to mentioned IEEE standard.
The output on my machine (Mac OS X 10.6, gfortran 4.5.1) is:
So Fortran's default real kind is not equal to IEEE standard single-precision float kind.
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.
implicit none
来要求显式声明所有变量。real*4
。-fdefault-real-8
强制将所有声明为real
的变量解释为real*8
注意(为了编写更多代码,不一定要尝试解决当前的错误):
如果您使用的是 Fortran 90 代码,则可以将
real(kind=4)
或real(kind=8)
与 gfortran 结合使用,而不是使用real*4
或real*8
语法。我不再使用命令行标志设置实数或整数大小,而是使用整数,参数 :: REAL_SIZE 变量来保存适当的数字(我通常选择 4 或 8,因为所有我使用的编译器支持它们,但如果你想非常便携,你应该使用selected_real_kind
例程)implicit none
.real*4
.-fdefault-real-8
to force all variables declared asreal
to be interpreted as areal*8
Note (for writing more code, not necessarily trying to solve the current bug):
If you're using Fortran 90 code, you can use
real(kind=4)
orreal(kind=8)
with gfortran rather than thereal*4
orreal*8
syntaxes. I've moved away from setting the real or integer size using command-line flags and instead use aninteger, parameter :: REAL_SIZE
variable to hold the appropriate number (I typically go for 4 or 8 because all the compilers I use support them, but if you want to be very portable you should use theselected_real_kind
routine)其中之一适用于大多数编译器,因为 Fortran 77:
或
Real
取决于体系结构;默认大小通常可以通过命令行选项进行修改。我没有任何与 Matlab 联系的经验。
One of these works with most compilers, since Fortran 77:
or
Real
is architecture dependent; the default size is usually modifiable by a command line option.I don't have any experience linking with Matlab.