Fortran 与派生类型的组件相关的分段故障
正如标题所示,我得到了一个与使用派生类型组件相关的seg错误。这是一个后续,但代表了一个更现实的用例。与前面的问题相反,不存在缺少显式接口的问题(下面的示例是没有子例程的单个程序,如果程序在更现实的用例中模块化,结果是相同的) 在一个更现实的用例中(在我的实际用例中),类型Fortran 与派生类型的组件相关的分段故障,fortran,gfortran,Fortran,Gfortran,正如标题所示,我得到了一个与使用派生类型组件相关的seg错误。这是一个后续,但代表了一个更现实的用例。与前面的问题相反,不存在缺少显式接口的问题(下面的示例是没有子例程的单个程序,如果程序在更现实的用例中模块化,结果是相同的) 在一个更现实的用例中(在我的实际用例中),类型表将在一个模块中定义,为了简洁起见,我只是将其组合在同一个位置。(我确实以这种方式进行了测试(使用模块中的类型定义),并且发生了完全相同的seg故障。) 这里至少有3个更改消除了segfault(就我而言,只有最后一个非常有效
表
将在一个模块中定义,为了简洁起见,我只是将其组合在同一个位置。(我确实以这种方式进行了测试(使用模块中的类型定义),并且发生了完全相同的seg故障。)
这里至少有3个更改消除了segfault(就我而言,只有最后一个非常有效)
表1
声明为数组col
可分配table1
声明为一个数组,似乎在某种程度上愚弄了编译器。此外,作为派生类型的组件也是一个重要方面
为了回答这个问题,我只是想对这里发生的事情做一个一般性的解释(包括这是否是某种bug)和关于避免这个问题的一般性建议——特别是,这里应该遵循哪些最佳实践来帮助我避免这个问题
请注意,这个问题部分与堆栈大小(例如,ulimit-s
)和shell交互有关,但在对前面问题的回答中,这个问题得到了很好的解决,我希望在这里研究这个问题的其他方面——这不是要最小化这个问题,而是要包括其他方面
编辑添加:@Steve评论说“这与Fortran毫无关系,更不用说gfortran了”。这也许是我问题的关键。我希望fortran编译器能够像我在这里使用的那样处理纯静态的声明,但可能我期望太多了。根问题是否可能是环境(即ulimit-s(8mb))和编译器标志之间的不匹配?编译器(gfortran或其他)是否无法查询环境或自动解决此问题
在@ripero对前一个问题的回答中,我很欣赏增加堆栈大小是有帮助的,尽管这对我来说有点不完整,因为问题不一定是堆栈大小,而是堆栈大小之间的某种不匹配(操作系统或环境级问题)还有编译器选项,如
-fmax stack var size
?但是,让数组可分配或使用编译标志在堆中创建数组仍然是一种方法。您显示的代码不是您编译的代码。@Steve对此表示感谢和抱歉。最后一行第二行的拼写错误,现已修复。我有表(1)
,但应该是表(1)
@JohnE,你到底想演示什么?你找到了另一种方法来耗尽你的精力!您的代码可以使用gfortran 6.4.1、7.3.1、8.1.1和9.x进行良好编译并执行。当然,我的默认堆栈大小是1GB。这与Fortran完全无关,更不用说gfortran了。顺便说一句,如果你打开优化,那么当DCE发生时,程序应该为你执行。@steve我编辑了这个问题,试图回答你的澄清请求。如果您愿意,请随时详细回答问题。如果这是一个愚蠢的问题,我表示歉意,但我可以告诉你,这是一次真诚的尝试,旨在了解根本原因,以及避免的最佳做法(不仅仅是快速修复)
! gfortran 4.8.5 on Red Hat linux
! default compile with no extra flags: "gfortran source.f90"
! default stack size = 8mb (ulimit -s)
program main
type table
real :: col(2100000) = 0.0 ! but OK if no initial value
end type table
type(table) :: table1(2) ! but OK if not an array
table1(1)%col = 1.0 ! segfault here
end program main