【问题标题】:End of Record error when saving a variable保存变量时出现记录结束错误
【发布时间】:2015-04-07 10:28:31
【问题描述】:

当我运行在另一台计算机上正常运行的代码时出现运行时错误。

我想知道问题是否出在这台机器的 Fortran 编译器 (GCC 4.9.2) 上,因为以前的计算机使用的是以前的版本。

定义这样的变量时会出现问题:

在我定义的模块中

character(30),allocatable,save :: sceneclass(:)

然后在子程序中sceneclass是根据

character(30) surf, frac, scene

allocate(sceneclass(10)) 

do i=1,10
write(sceneclass(i),*) trim(scene)//trim(surf)//'_'//trim(frac)
enddo

在第一次迭代中,我得到“记录结束”。但我不知道问题出在哪里。它似乎在其他计算机上也能正常工作。

【问题讨论】:

  • scene surffrac 的值是多少?您可能必须创建一个完全可编译的示例。

标签: fortran runtime-error


【解决方案1】:

您可能正在向sceneclass(i) 写入一个字符串,该字符串比您指定的 30 个字符长。

我可以复制这个

program test
  implicit none
  character(10),allocatable :: sceneclass(:)
  integer                   :: i

  allocate( sceneclass(10) ) 

  do i=1,10
    write(sceneclass(i),*) 10**i
  enddo

  print *, ( trim(sceneclass(i)), i=1,10 )

end program

gfortran 失败并显示

Fortran 运行时错误:记录结束

ifort 正确报告错误:

输出语句溢出记录,单元-5,文件内部列表定向写入

将字符串长度增加到 12 可以解决这种情况下的问题。您可以(并且应该)在write 语句中使用iostat 来捕获这一点。

【讨论】:

  • 我在 GCC 站点创建了一个feature request/bug report
  • 这就是问题所在。出于同样的原因,使用以前的 gcc fortran 版本,空白不是问题。谢谢!
  • @cardogar 空白应该不是问题!顺便说一句,这就是为什么我问你写的那些变量中有什么,因为它看起来像溢出。您应该始终在您的问题中提供完整的信息。而且我不认为错误信息是错误的,它或多或少相当于intel的。
  • @VladimirF 可能,但它具有误导性(在我看来)。 Intel的错误信息直接导致了问题的原因。
  • 我可以想象一些编译器盲目地写入内存中相邻的任何内容。你能具体说一下哪个旧版本接受了这个吗?
【解决方案2】:

需要注意的一点,当您指定一个指向* 写入字符串的列表时,编译器总是(?)添加一个额外的前导空格,因此您可以写入的字符串的有效长度少一超出您的预期。

为了解决这个问题(当然,假设你不想要前导空白)使用字符串编辑描述符:

   write(sceneclass(i),'(a)')...

有趣的是ifort (linux 11.1) 实际上允许你超过一个字符:

 character*5 c
 write(c,*)'12345'  ! result: " 1234"

我认为这是一个错误。似乎他们也忘记计算空白了..(gfortran 会在此引发上述错误,如果再添​​加一个字符,ifort 会拒绝)

如果你想知道为什么是空白,请看这里。Are Fortran control characters (carriage control) still implemented in compilers?

现在我很好奇某处的某个编译器是否没有为内部列表写入执行此操作,或者您的代码之前可能是用一个标志编译的以禁用“打印机控制”代码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2015-12-17
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多