【问题标题】:Fortran array pointers to scalarFortran 数组指针指向标量
【发布时间】:2016-05-25 08:56:28
【问题描述】:

在 Fortran 中,您可以使用指针重塑数组:

program working

  implicit none

  integer, dimension(:,:), pointer :: ptr
  integer, dimension(6), target :: trg

  trg = (/1,2,3,4,5,6/)
  ptr(1:2,1:3) => trg

  ! Here, you can use the 6-sized 1D array trg
  ! or the 2 by 3-sized 2D array ptr at the same time.
  ! Both have the same content (6 integers), but are only indexed
  ! differently.

  write(*,*) ptr(1,2)

end program working

这个程序写“3”,这是根据reshape规则。

同样,我也尝试过这样做,但不是从 1D 到 2D,而是从 0D 到 1D。

program not_working

  implicit none

  integer, dimension(:), pointer :: ptr
  integer, target :: trg

  trg = 1
  ptr(1:1) => trg

  ! I hoped to be able to use the scalar trg at the same time as
  ! the one-sized 1D array ptr. I thought they both have the same
  ! content, but are only indexed differently.

  write(*,*) ptr(1)

end program not_working

我预计会看到“1”。但它不会编译。

Gfortran 4.9 说:

错误:等级重新映射目标必须是等级 1 或简单地连续 (1)

Ifort 14.0.2 说:

.f90:灾难性错误:内部编译器错误: 出现分段违规信号请同时报告此错误 在软件问题中发生的情况 报告。注意:给出的文件和行可能不是导致此问题的明确原因 错误。 .f90(代码 1)的编译中止

我不明白标量 trg 怎么可能不连续以及两个示例程序之间的根本区别是什么。

【问题讨论】:

  • 使用标签fortran 并在必要时为特定版本添加另一个标签(不在此处)。您实际上使用的是 Fortran 2003 功能。
  • Internal compiler error 在编译器中总是错误。它可能是由无效代码引起的,但始终是编译器中的错误。即使您提供错误的代码,编译器也不应该崩溃。它还清楚地说明了您应该做什么“请在软件问题报告中报告此错误以及它发生的情况。”您完成了吗?
  • 请注意,Intel 14 版本有点旧,您应该考虑升级。

标签: pointers fortran reshape rank


【解决方案1】:

标量不是简单的连续数组,因为它根本不是数组。它是如此简单。 Gfortran 检测到它并抱怨,ifort 感到困惑并崩溃。但是您的代码无效,您不能将数组指针指向标量。

【讨论】:

    【解决方案2】:

    数组指针旨在指向数组,因此不能指向标量(相反,我们可以为此目的使用标量指针)。但是如果我们确实想使用数组指针来指向标量(出于某种原因),我们可以使用c_f_pointer() 这样

    use iso_c_binding
    
    integer, target :: a
    integer, pointer :: p(:), q(:,:), r(:,:,:)
    
    a = 777
    
    call c_f_pointer( c_loc( a ), p, [1] )
    call c_f_pointer( c_loc( a ), q, [1,1] )
    call c_f_pointer( c_loc( a ), r, [1,1,1] )
    
    print *, "p = ", p(:),     "with shape", shape(p)
    print *, "q = ", q(:,:),   "with shape", shape(q)
    print *, "r = ", r(:,:,:), "with shape", shape(r)
    

    但这显然是一个“不安全”的特性(从某种意义上说,它允许访问原始内存),如果使用错误的参数,它可能会给出错误的结果(甚至是灾难),例如:

    call c_f_pointer( c_loc( a ), p, [3] )
    
    print *, "p = ", p(:)   !! gives "p =  777  202 0" etc with garbage data
    

    所以,除非有特殊原因,我认为对标量变量使用标量指针可能会更好(更安全)...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      相关资源
      最近更新 更多