奇怪的错误是链接的结果:“不同结构类型的赋值是无效的。”

时间:2013-06-26 20:27:00

标签: fortran

前几天我需要一些问题的帮助,并在这里充实了一个非常简单的例子:fortran "array of arrays" and "pack" issues。这个新颖的例子最终成功了,但它没有解决我的大项目的问题。为了进一步理解我得到的错误,我扩展了小说程序,以更准确地模仿我的大型程序的结构。事实证明这确实重现了我的错误。以下是我使用的代码:

test.f90

program main

use locs, only: alloc_locs,all_locs
implicit none
INCLUDE 'test.h'
integer :: numpars, numlocs, n

type (par), allocatable, dimension(:) :: all_pars

CALL alloc_locs

!read numpars, numlocs from file etc
numpars = 10

allocate(all_pars(numpars))

!initialize all_pars
all_pars(1:4)%location = 1
all_pars(5:6)%location = 2
all_pars(7:8)%location = 3
all_pars(9:10)%location = 4


!get particles in each location 
do n = 1,numlocs
  all_locs(n)%pars = pack(all_pars, (all_pars(:)%location .eq. n)) 
enddo

write(*,*) all_locs(2)%pars(1)%location
end program

test.h

type par
  !data
  integer :: location
end type par

type locations
  ! data
  type (par), allocatable, dimension(:) :: pars
end type locations

locs.f90

MODULE LOCS

IMPLICIT NONE
PUBLIC
SAVE

include 'test.h'
type (locations), allocatable, dimension(:) :: all_locs
CONTAINS
SUBROUTINE alloc_locs()

  integer :: numlocs

  numlocs = 4
  allocate(all_locs(numlocs))

END SUBROUTINE alloc_locs
END MODULE LOCS

生成文件

FC = ifort

OBJS          = locs.o

FFLAGS =  -vec-report0 -O2 -fp-model precise -standard-semantics

test : $(OBJS)
    @echo "  Compiling"
    @$(FC) $(FFLAGS) -o test.exe test.f90 $(OBJS) 
    @\rm *.o *.mod
    @echo "  "
    @echo "  Compilation Successfully Completed"
    @echo "  "

%.o: %.f90
    @echo "  Compiling $<"
    @$(FC) $(FFLAGS) -c $<

clean:
    \rm *.o *.mod test.exe

make的结果:

Compiling locs.f90
Compiling
test.f90(27): error #6197: An assignment of different structure types is invalid.
  all_locs(n)%pars = pack(all_pars, (all_pars(:)%location .eq. n))
---------------------^
compilation aborted for test.f90 (code 1)     

对我来说,这段代码和前一个问题的代码在功能上是相同的,但显然有些东西在与模块结构有关的翻译中丢失了,或者两次引用test.h,结构不知道等同。我在网上找到关于这个错误的信息很少,而且就我的问题而言,没有任何与我的问题相关的信息。有人可以解释导致问题的原因,以及我可能如何对其进行排序?如果问题是后者,那么如何在模块之间传播用户定义的类型?

提前致谢。

1 个答案:

答案 0 :(得分:4)

我认为您对include 'test.h'的使用可能是您问题的根源......

在编写代码时,您在两个不同的范围内声明类型parlocations,一旦进入程序内部,一旦进入模块内部。尽管它们具有相同的名称,但这些派生类型是不同的类型。您没有使用它们从模块到程序的关联这一事实不会影响它。因此,程序中的变量all_pars的类型为program::par(原样)。程序内的alloc_locs调用会导致all_locs类型module::locations,并且该类型的每个实例都有module::par类型的组件。所以在这个声明中

all_locs(n)%pars = pack(all_pars, (all_pars(:)%location .eq. n))
lhs 上的

类型为module::par,而 rhs 上的类型为program::par

或类似的东西,但说实话,我觉得你的代码非常复杂。我不明白你为什么要两次定义parlocations,为什么你不简单地在模块中声明它们并使用 - 关联它们。

你问如何在模块之间传播用户定义的类型?答案是你在一个模块中定义它并从其他模块或程序本身使用它。