# Data-pointer-object and unlimited polymorphic target

**URL:** <https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983>\
**Category:** Help\
**Created:** [December 18, 2024, 10:13am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983 "2024-12-18T10:13:54Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [December 18, 2024, 10:13am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/1 "2024-12-18T10:13:55Z")

</div>

```fortran
program main
    implicit none
    type pair
        sequence
        real::x
        integer::y
    end type pair
    type(pair),target::p
    type(pair),pointer::ptr_pair
    integer,target::i
    integer,pointer::i_ptr
    p=pair(1.0,2)
    ptr_pair=>view(p)
    print*,ptr_pair
    i=1  
    i_ptr => view(i)!WRONG
    print*,i_ptr
contains
   function view(a)result(b)
      class(*),intent(in),target::a
      class(*),pointer::b
      b=>a
   end function view
end program main

```

Compilation error

```sh
app/example.f90:16:5:

   16 | i_ptr => view(i)
      | 1 ~~~~~
Error: Data-pointer-object at (1) must be unlimited polymorphic, or of a type with the BIND or SEQUENCE attribute, to be compatible with an unlimited polymorphic target

```

Why intrinsic type pointer not permit point to polymorphic, but user defined type allowed. Is intrinsic type has `sequence` attribute?

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [December 18, 2024, 10:25am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/2 "2024-12-18T10:25:18Z")

</div>

I think the reason is that a derived type can be used as the parent of another type, whereas intrinsic types cannot. (At least that seems a plausible difference :).) It does not matter whether there are any actual procedures/methods connected to the type.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 18, 2024, 10:57am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/3 "2024-12-18T10:57:41Z")

</div>

Worth testing with different compilers.

Flang:

```txt
error: Semantic errors in /app/example.f90
/app/example.f90:13:5: error: function result type 'CLASS(*)' is not compatible with pointer type 'pair'
      ptr_pair=>view(p)
      ^^^^^^^^^^^^^^^^^
/app/example.f90:16:5: error: function result type 'CLASS(*)' is not compatible with pointer type 'INTEGER(4)'
      i_ptr => view(i)!WRONG
      ^^^^^^^^^^^^^^^^
Compiler returned: 1

```

NAG:

```txt
> nagfor example.f90 
NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7203
Error: example.f90, line 16: Pointer assignment of CLASS(*) target to INTEGER pointer
[NAG Fortran Compiler error termination, 1 error]

```

Seems a bit like a dark corner of the language. It is probably worth looking into the J3 Fortran interpretation document to see what it says about a pointer to an unlimited polymorphic variable.

---

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [December 18, 2024, 12:54pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/4 "2024-12-18T12:54:21Z")

</div>

As shown in [24-007.pdf](https://j3-fortran.org/doc/year/24/24-007.pdf), same as gfortran report

```plaintext
C1017 (R1034) If data-target is unlimited polymorphic, data-pointer-object shall be unlimited polymorphic, or 
of a type with the BIND attribute or the SEQUENCE attribute.

```

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [December 18, 2024, 1:15pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/5 "2024-12-18T13:15:00Z")

</div>

> [@Euler-37](#):
>
> ```auto
> or of a type with the BIND attribute or the SEQUENCE attribute.
> 
> ```

I did not know about this, but omg, who thought this was a good idea?

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 18, 2024, 1:25pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/6 "2024-12-18T13:25:41Z")

</div>

Seems like it has something to do with alignment constraints which both C structs and sequence types have.  
It also suggests a workaround to get the desired result:

```auto
    type :: int_seq
        sequence
        integer :: i
    end type
    integer,target::i
    type(int_seq),pointer::i_ptr
    i=1  
    i_ptr => view(i) ! Now it works
    print*, i_ptr%i

```

It does look like a [loophole](https://fortran-lang.discourse.group/t/implicit-real-complex-conversion-in-fortran/7381/38) in the Wirth sense.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [December 18, 2024, 2:44pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/7 "2024-12-18T14:44:11Z")

</div>

> [@ivanpribec](#):
>
> It does look like a [loophole](https://fortran-lang.discourse.group/t/implicit-real-complex-conversion-in-fortran/7381/38) in the Wirth sense.

Exactly. Why on earth would you want something like this to be valid?

```auto
type :: four_bytes
  sequence
  integer(c_int8) :: i1, i2, i3, i4
end type
type(who_tf_knows), target :: thing
type(four_bytes), pointer :: rep
thing = ...
! lets just see what four of the bytes
! starting at the beginning of this object look like
rep => view(thing)
print *, rep

```

I’m guessing there is some other text somewhere that still says this is invalid, but the compiler really ought to yell loudly about it.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 18, 2024, 3:05pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/8 "2024-12-18T15:05:26Z")

</div>

Maybe it is useful to write some dictionary-like object where the return type is polymorphic? But I don’t understand why intrinsic types aren’t supported, if `sequence` types are. It would be nice to hear from the standard-bearers on why they thought this feature is useful.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [December 18, 2024, 6:51pm UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/9 "2024-12-18T18:51:54Z")

</div>

> [@everythingfunctional](#):
>
> I’m guessing there is some other text somewhere that still says this is invalid,

Yep, found it. 10.2.2.3 Data pointer assignment

> If the pointer object is of a type with the BIND attribute or the SEQUENCE attribute, the dynamic type of the pointer target shall be that type.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 19, 2024, 9:28am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/10 "2024-12-19T09:28:53Z")

</div>

I think that is still interesting, because you can write a function that returns objects with different dynamic types:

```fortran
module tmod
    implicit none
    type :: t_int
        integer :: val
    end type
    type :: t_real
        real :: val
    end type
    type :: t_logical
        sequence
        logical :: val = .false.
    end type

    integer, parameter :: tf_int = 1
    integer, parameter :: tf_real = 2
    integer, parameter :: tf_logical = 3

    type(t_int), target :: a = t_int(42)
    type(t_real), target :: b = t_real(33.0)
    type(t_logical), target :: c

contains

    function ret(iflag)
        integer :: iflag
        class(*), pointer :: ret
        select case(iflag)
        case(tf_int)
            ret => a
        case(tf_real)
            ret => b
        case(tf_logical)
            ret => c
        case default
            ret => null()
        end select
    end function

end module

program main
    use tmod

    integer :: i, iflag
    class(*), pointer :: r
    type(t_logical), pointer :: rl

    iflag = 1
    do i = 1, 9
        
        r => ret(iflag)
        if (.not. associated(r)) cycle
        if (iflag == tf_logical) then
            rl => r
            print *, rl%val
        else
            select type(r)
            type is (t_int)
                print *, r%val
            type is (t_real)
                print *, r%val
            end select
        end if
        iflag = modulo(i,3) + 1
    end do

end program

```

---

<div class="post-metadata">

**Author:** ![Euler-37](https://avatars.discourse-cdn.com/v4/letter/e/b19c9b/32.png) [@Euler-37](https://fortran-lang.discourse.group/u/Euler-37)\
**Post date:** [December 19, 2024, 9:31am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/11 "2024-12-19T09:31:10Z")

</div>

By the way, I wish that fortran intrinsic function like `findloc` can be used for user defined type with `sequence` attribute.It just combined with static type,so it should have something like `Eq Trait`

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [December 19, 2024, 11:33am UTC](https://fortran-lang.discourse.group/t/data-pointer-object-and-unlimited-polymorphic-target/8983/12 "2024-12-19T11:33:39Z")

</div>

Can’t you just use component selection?

```auto
type :: t_int
   sequence
   integer :: val 
end type

type(t_int) :: a(100)

a = t_int(100)
a(42) = t_int(1)

print *, find(a, t_int(1))

contains
    
    pure function find(a, val) result(res)
        type(t_int), intent(in) :: a(:), val
        integer :: res
        intrinsic :: findloc
        res = findloc(a%val,val%val,dim=1)
   end function

end

```
