通过指针引用重叠数组
Referencing overlapping arrays through pointers
我需要使用调整到重叠数组的指针执行 memmove()
风格的操作。更准确地说,我需要将 b(:)
复制到 a(:)
.
在 C 编程语言中我会调用 memmove(a, b, N)
。但是,据我所知,Fortran 标准在指针别名方面非常严格。
那么,以下三个选项中哪一个可以安全使用(根据标准),哪个会导致未定义的行为:
- 带有别名指针的向量语法(选项 1),
- 使用别名指针的显式循环(选项 2),
- 调用将重叠数组作为参数的例程(选项 3)
?
program ptr
implicit none
integer, parameter :: ARRAY_SIZE = 10, N = 6
integer, target :: array(ARRAY_SIZE)
integer, dimension(:), pointer :: a, b
integer :: i
a => array(1: N)
b => array(3: N+2)
! Option 1
a(1: N) = b(1: N)
! Option 2
do i = 1, N
a(i) = b(i)
end do
! Option 3
call foobar(a, b, N)
contains
subroutine foobar(a, b, length)
integer, dimension(:), intent(out) :: a
integer, dimension(:), intent(in) :: b
integer, intent(in) :: length
a(1: length) = b(1: length)
end subroutine foobar
end program ptr
选项 1 和 2 都可以,编译器知道指针可以别名。
子例程本身没问题,但你不能向其传递两个别名参数,这确实违反了标准(未定义行为是 C 术语)。您可以使用参数 pointer
,然后可以使用别名并且程序将符合标准。
integer, dimension(:), pointer :: a
integer, dimension(:), pointer :: b
我还删除了意图,因为它们与指针关联状态有关,而不是目标值,正如 IanH 评论的那样。此外,他们还需要 Fortran2003。
我需要使用调整到重叠数组的指针执行 memmove()
风格的操作。更准确地说,我需要将 b(:)
复制到 a(:)
.
在 C 编程语言中我会调用 memmove(a, b, N)
。但是,据我所知,Fortran 标准在指针别名方面非常严格。
那么,以下三个选项中哪一个可以安全使用(根据标准),哪个会导致未定义的行为:
- 带有别名指针的向量语法(选项 1),
- 使用别名指针的显式循环(选项 2),
- 调用将重叠数组作为参数的例程(选项 3)
?
program ptr
implicit none
integer, parameter :: ARRAY_SIZE = 10, N = 6
integer, target :: array(ARRAY_SIZE)
integer, dimension(:), pointer :: a, b
integer :: i
a => array(1: N)
b => array(3: N+2)
! Option 1
a(1: N) = b(1: N)
! Option 2
do i = 1, N
a(i) = b(i)
end do
! Option 3
call foobar(a, b, N)
contains
subroutine foobar(a, b, length)
integer, dimension(:), intent(out) :: a
integer, dimension(:), intent(in) :: b
integer, intent(in) :: length
a(1: length) = b(1: length)
end subroutine foobar
end program ptr
选项 1 和 2 都可以,编译器知道指针可以别名。
子例程本身没问题,但你不能向其传递两个别名参数,这确实违反了标准(未定义行为是 C 术语)。您可以使用参数 pointer
,然后可以使用别名并且程序将符合标准。
integer, dimension(:), pointer :: a
integer, dimension(:), pointer :: b
我还删除了意图,因为它们与指针关联状态有关,而不是目标值,正如 IanH 评论的那样。此外,他们还需要 Fortran2003。