【问题标题】:Fortran weird assignment, is 4294967295 == .true.?Fortran 奇怪的赋值,是 4294967295 == .true.?
【发布时间】:2016-11-14 17:25:03
【问题描述】:

我有一个像这样的 fortran 子例程。

subroutine load_ed_ecosystem_params()

   use pft_coms    , only : include_these_pft   & ! intent(in)
                          , is_tropical         & ! intent(out)
                          , is_liana              ! intent(out)
   implicit none
   !---------------------------------------------------------------------------------------! 
   !    This flag should be used to define whether the plant is tropical/subtropical or    !
   ! not.                                                                                  !
   !---------------------------------------------------------------------------------------! 
   is_tropical(1:4)   = .true.
   is_tropical(5:11)  = .false.
   is_tropical(12:13) = .false.
   is_tropical(14:15) = .true.
   is_tropical(16)    = .true.
   is_tropical(17)    = .true.
   !---------------------------------------------------------------------------------------!

   !---------------------------------------------------------------------------------------!
   !    This flag should be used to define whether the plant is a liana or not             !
   !---------------------------------------------------------------------------------------!
   is_liana(1:16)  = .false.
   is_liana(17)    = .true.
   !---------------------------------------------------------------------------------------!

is_tropicalis_liana 数组在 pft_coms.f90 文件中定义。 数组采用了奇怪的值,所以我在 gdb 中运行可执行文件。我在作业之前和之后打破了文件。作业前我得到

Breakpoint 1, load_ed_ecosystem_params () at ed_params.f90:87
87     is_tropical(1:4)   = .true.

(gdb) print is_tropical
$2 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE.)

(gdb) print is_liana   
$3 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE.) 

他们应该这样做,因为它们是以这种方式初始化的。在运行了下几行之后,我得到了

(gdb) n
88     is_tropical(5:11)  = .false.
(gdb) n
89     is_tropical(12:13) = .false.
(gdb) n
90     is_tropical(14:15) = .true.
(gdb) n
91     is_tropical(16)    = .true.
(gdb) n
96     is_tropical(17)    = .true.
(gdb) n
102    is_liana(1:16)  = .false.
(gdb) n
103    is_liana(17)    = .true.
(gdb) print is_tropical
$4 = (4294967295, 4294967295, 4294967295, 4294967295, .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., 4294967295, 4294967295, 4294967295, 4294967295)
(gdb) print is_liana
$6 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., 4294967295)

为什么向量被分配整数 2^32 - 1 而不是逻辑.true.

【问题讨论】:

  • 这看起来就像 GDB 解释值的问题。但我认为这是一个.TRUE。实际上。您是否直接注意到 Fortran 中的任何问题?
  • 是的,最终这会导致 SegFault 错误:forrtl: Serious (408): fort: (2): 数组 IS_LIANA 的下标 #1 的值 65 大于17的上限
  • 我猜段错误与这个问题无关。顺便说一句,从技术上讲,这不是段错误,而是编译器检查发现错误。您应该阅读该消息并检查您的界限。
  • 是的,对不起,我不知道为什么我认为这是一个段错误

标签: segmentation-fault fortran gdb variable-assignment


【解决方案1】:

一些 Fortran 编译器(尤其是 Intel Fortran)使用 -1 位模式来表示 .TRUE.,而一些使用 +1。

看起来 GDB 期望 +1 为 .TRUE。并且不知道 4294967295 也是 .TRUE.,只是在不同的编译器中。

无符号整数 4294967295 与有符号整数 -1 具有相同的位模式。所有位都设置为 1。

您可以通过-standard-semantics-fpscomp logicals 更改此行为。英特尔 Fortran 将使用 +1 作为 .TRUE..

【讨论】:

  • 所以我不确定你的答案,一方面我确实使用 intel 编译,另一方面如果我使用idb 调试,我注意到完全相同的行为。英特尔调试器也应该发生这种情况吗?
  • 它可能,谁知道,英特尔有两种不同的操作模式,而 idb 只为其中一种准备。
  • 通常使用 -check bounds(或 -check all)编译将有助于解决段错误的常见原因。有一个类似的 gfortran 开关。
  • @Holmz 值得注意的是,OP 已准备好使用此开关,而他的错误消息正是来自该检查。然而,这是一个不同的问题。此答案未涵盖,编辑后的问题也未涵盖。他没有段错误。请参阅问题下方的 cmets。
猜你喜欢
  • 2011-04-08
  • 1970-01-01
  • 2013-08-19
  • 2012-12-15
  • 2020-11-08
  • 2014-11-04
  • 2015-04-01
  • 2017-11-07
相关资源
最近更新 更多