Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend move_alloc to unlimited polymorphic variables #345

Open
ivan-pi opened this issue Nov 21, 2024 · 6 comments
Open

Extend move_alloc to unlimited polymorphic variables #345

ivan-pi opened this issue Nov 21, 2024 · 6 comments

Comments

@ivan-pi
Copy link

ivan-pi commented Nov 21, 2024

Originally discussed here: https://fortran-lang.discourse.group/t/ownership-for-fortran-pointers/8084/55?u=ivanpribec

The proposal would be to provide a means of move allocation from unlimited polymorphic to other allocatable variables (assuming that the types are consistent).

type :: heavy_type
   real :: a(1000)
end type

class(*), allocatable :: a1
class(heavy_type), allocatable :: a2

allocate(a2)
call move_alloc(from=a2,to=a1)  ! Compiles with gfortran, ifx, and flang

! Fails (from and to must be of the same type and kind)
call move_alloc(from=a1,to=a2) 

select type(a1)
class is (heavy_type)
    ! Fails (from argument must be allocatable)
    call move_alloc(from=a1,to=a2) 
end select

end

The standard currently says in 11.1.3.3

The associating entity does not have the ALLOCATABLE or POINTER attributes;

Just a thought, perhaps the semantics of move_alloc could be extended, such that:

call move_alloc(from,to[,stat])

would apply to any two allocatable variables including polymorphic ones. When types don't belong to the same hierarchy, it should obviously fail. In the case that from and to are both polymorphic it requires some thought of what should happen allocating from child to parent (some data members would be destroyed) or parent to child (some data members would remain uninitialized).

cc @everythingfunctional @gronki

@everythingfunctional
Copy link
Member

There's certainly something to be done here. I'm not quite sold on the stat argument approach, but it's not terrible. We could also do some sort of carve out in the select type construct.

@klausler
Copy link

I'm unable to think of a good reason why the selector can't have the ALLOCATABLE or POINTER attributes within a TYPE IS clause.

@ivan-pi
Copy link
Author

ivan-pi commented Nov 21, 2024

Even if there ain't a reason, the nested select type statements needed are an eyesore:

select type(a1)
type is (heavy_type)
  select type(a2)
  type is (heavy_type)
    call move_alloc(from=a1,to=a2)
  end select
end select

@klausler
Copy link

I see your point, but the inner SELECT TYPE construct isn't needed to guarantee type compatibility.

@everythingfunctional
Copy link
Member

I'm unable to think of a good reason why the selector can't have the ALLOCATABLE or POINTER attributes within a TYPE IS clause.

The selector does have the ALLOCATABLE or POINTER attribute, but the associate-name is what has the correct type, and it doesn't have the allocatable or pointer attributes because it might be associated with the result of an expression.

@klausler
Copy link

Let me try again. I can't think of a good reason why the associate-name x in SELECT TYPE (x => allocatable) can't have the ALLOCATABLE attribute in a TYPE IS block when allocatable is in fact an ALLOCATABLE variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants