# Is it possible to initialize a linked list?

**URL:** <https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064>\
**Category:** Help\
**Created:** [January 20, 2023, 8:44pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064 "2023-01-20T20:44:38Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 20, 2023, 8:44pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/1 "2023-01-20T20:44:38Z")

</div>

Consider the following example of a linked list.

```auto
program pllassign
   implicit none
   type ll
      integer :: i=-1
      type(ll), pointer :: next=>null()
   end type ll
   type(ll), target, save :: first, second, third
   type(ll), pointer :: current => first
   third = ll(3,null())
   second = ll(2,third)
   first = ll(1,second)
   do while (associated(current))
      write(*,*) 'current%i=', current%i
      current => current%next
   enddo
end program pllassign

```

This works as intended, with output like:

```auto
$ gfortran pllassign.f90 && a.out
 current%i= 1
 current%i= 2
 current%i= 3

```

It occurred to me that it might be nice if the linked list could be constructed with initialization rather than assignment. So I tried this:

```auto
program pllinit
   implicit none
   type ll
      integer :: i=-1
      type(ll), pointer :: next=>null()
   end type ll
   type(ll), target, save :: third = ll(3,null())
   type(ll), target, save :: second = ll(2,third)
   type(ll), target, save :: first = ll(1,second)
   type(ll), pointer :: current => first
   do while (associated(current))
      write(*,*) 'current%i=', current%i
      current => current%next
   enddo
end program pllinit

```

This does not compile, with either gfortran or NAG, so I figure I must be doing something wrong. Is it possible to construct a linked list using pointers with initialization?

NOTE: Of course, in fortran, one would not use `pointer` elements of the `ll` derived type, one would naturally use `allocatable` instead. However, I already know that it is not allowed to initialize an `allocatable` variable, so I’m using `pointer` instead in these examples just because of that language limitation.

EDIT: I changed the original DO loop to a simpler DO WHILE loop.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 20, 2023, 9:01pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/2 "2023-01-20T21:01:21Z")

</div>

Ignore this - see below.

Fortran 2008 allows an _initial-data-target_ as the initialization for a pointer variable. However, the target must be a variable, not a structure constructor. The constraint is:

> C765 A designator that is an initial-data-target shall designate a nonallocatable, noncoindexed variable that has the TARGET and SAVE attributes and does not have a vector subscript. Every subscript, section subscript, substring starting point, and substring ending point in designator shall be a constant expression.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 20, 2023, 9:13pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/3 "2023-01-20T21:13:28Z")

</div>

Thanks for the reply. In the code above, the pointer assignment (`next`) is to a variable (e.g. `second`). The pointer assignment occurs within the structure constructor `ll()`, but the structure constructor itself is not the target. The variable (e.g. `second`) does have the TARGET and SAVE attributes, as required. So I thought I had dodged that bullet.

Also, in the first code, which does compile and work, the pointer initialization

```auto
type(ll), pointer :: current => first

```

occurs. This is also a pointer assignment to a variable (`first` in that case) of that same derived type `ll`.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 20, 2023, 9:42pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/4 "2023-01-20T21:42:04Z")

</div>

Sorry, I missed an important thing. These are not initial-data-targets, but just initialization, which means a constant expression is required.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 20, 2023, 9:47pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/5 "2023-01-20T21:47:40Z")

</div>

I experimented with this a little to try to understand this. The first initialization

```auto
   type(ll), target, save :: third = ll(3,null())

```

seems to work. The following two

```auto
   type(ll), target, save :: second = ll(2,third)
   type(ll), target, save :: first = ll(1,second)

```

are what causes the problem. Is that because `third` has a constant expression, while `second` and `first` do not?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 20, 2023, 9:56pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/6 "2023-01-20T21:56:10Z")

</div>

> [@RonShepard](#):
>
> Is that because `third` has a constant expression, while `second` and `first` do not?

Yes, exactly.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 20, 2023, 10:20pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/7 "2023-01-20T22:20:26Z")

</div>

Ok, I think the following code is as close as I can get to what I wanted to do:

```auto
program pllinit
   implicit none
   type ll
      integer :: i=-1
      type(ll), pointer :: next=>null()
   end type ll
   type(ll), target, save :: third = ll(3,null())
   type(ll), target, save :: second = ll(2,null())
   type(ll), target, save :: first = ll(1,null())
   type(ll), pointer :: current => first
   first%next => second
   second%next => third
   do while (associated(current))
      write(*,*) 'current%i=', current%i
      current => current%next
   enddo
end program pllinit

```

Here the linked list data value is initialized at declaration, but the pointer component must be assigned at run time. Oddly, the pointer initialization of `current` is allowed at declaration.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 20, 2023, 10:35pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/8 "2023-01-20T22:35:24Z")

</div>

> [@RonShepard](#):
>
> Oddly, the pointer initialization of `current` is allowed at declaration.

That’s because `first` is a _valid initialization-data-target_.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 20, 2023, 10:50pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/9 "2023-01-20T22:50:47Z")

</div>

Yes, but do you see the basis for the confusion? Consider the following:

```auto
   type(ll), target, save :: third = ll(3,null())
   type(ll), target, save :: second = ll(2,third)                                                                         
   type(ll), pointer :: current => third

```

This does not compile, but remove the second line and it does. The pointer component `second%next` cannot point to the target `third`, while `current` can.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 20, 2023, 11:03pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/10 "2023-01-20T23:03:49Z")

</div>

No, I don’t see a problem with this. `third` is not a pointer, and is initialized to a constant structure constructor - fine. `current` is a pointer and has a target, save variable as its initialization-data-target - fine. `second` is not a pointer and is initialized to a non-constant expression - not fine.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 21, 2023, 7:02pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/11 "2023-01-21T19:02:19Z")

</div>

To spell this out in detail, a programmer would consider the declaration

```auto
type(ll), target, save :: second = ll(2,third)

```

to be equivalent to something like

```auto
second%i = 2
second%next => third

```

That pointer initialization seems like it should have the same kinds of restrictions as the following pointer initialization

```auto
current => third

```

That latter one is legal, while the former one is not. They both have the same information available at compile time, so I do not understand why the language restricts one but allows the other. Yes, I see that one pointer is on the right hand side of the declaration, while the other is on the left, but that seems to be just an artificial distinction in this case. If a compiler has the information to do one, it has that exact same information available to do the other.

As a practical matter, it would be quite useful if programmers could initialize data structures such as linked lists, trees, graphs, networks, heaps, and so on. By initialize, I mean at compile time on the declaration statement, not at run time with an initialization routine that uses assignments. Is there any chance that this capability could be added to the language?

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [January 21, 2023, 10:10pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/12 "2023-01-21T22:10:38Z")

</div>

> [@RonShepard](#):
>
> … They both have the same information available at compile time, so I do not understand why the language restricts one but allows the other. … Is there any chance that this capability could be added to the language?

@RonShepard ,

You may want to first summarize your idea(s) or change request(s) in a post the GitHub J3 Fortran site.

Also, why don’t you join the J3 Fortran committee? If not, please review the link below for the last available [**minutes**](https://j3-fortran.org/doc/year/22/minutes227.txt) of the meeting from July of last year - see if there are any institutions and/or representatives through whom you can try to table specific requests for the next or subsequent revisions to the standard. That way, the proposals of interest to you and the teams you work with can get more attention that what happens with discussion threads at comp.lang.fortran, this discourse, etc.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [January 21, 2023, 10:52pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/13 "2023-01-21T22:52:05Z")

</div>

As far as I can guesstimate from the standard, there is no technical reason for the current restriction. The relaxation brought about by Fortran 2008 was not extended to component initialization of objects of types with derived type components of `POINTER` attribute via structure constructors. I think it is an oversight. Thus the restriction remains as it does with other components of derived types, meaning with the code below `block4` is treated as `block3` instead of `block2` and `block1`.

```fortran
   block1: block
      integer, target :: a = 42
      integer, pointer :: x => a !<-- Allowed
   end block block1
   block2: block
      type :: t
         integer :: n = 0
      end type
      type(t), target :: a
      type(t), pointer :: x => a !<-- Allowed
   end block block2
   block3: block
      type :: t
         integer :: n = 0
      end type
      integer :: a = 42
      type(t) :: x = t( n=a ) !<-- Not Allowed
   end block block3
   block4: block
      type :: t
         integer, pointer :: n => null()
      end type
      integer, target :: a = 42
      type(t) :: x = t( n=a ) !<-- Not Allowed
   end block block4
end 

```

```auto
C:\temp>gfortran -c q.f90
q.f90:17:26:

   17 | type(t) :: x = t( n=a ) !<-- Not Allowed
      | 1
Error: Parameter 'a' at (1) has not been declared or is a variable, which does not reduce to a constant expression
q.f90:24:26:

   24 | type(t) :: x = t( n=a ) !<-- Not Allowed
      | 1
Error: Parameter 'a' at (1) has not been declared or is a variable, which does not reduce to a constant expression

```

So what this will take is papers at the J3 Fortran site that can help with discussion and also tabling the proposal at the J3 meeting(s) toward consideration now for Fortran 202Y and/or the next revision.

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 22, 2023, 1:39am UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/14 "2023-01-22T01:39:28Z")

</div>

Offhand, I agree with @FortranFan that the standard could be relaxed to allow a structure constructor where all non-pointer components are constant expressions and pointer components are either `null()` or a variable that meets the current requirements for _initial-data-target_.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 22, 2023, 3:55am UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/15 "2023-01-22T03:55:17Z")

</div>

There is an easy workaround for the block3 case.

```auto
block3: block
      type :: t
         integer :: n = 0
      end type
      integer, parameter :: aval = 42
      integer :: a = aval
      type(t) :: x = t( n=aval )
   end block block3

```

So that just leaves block4 as the oddball case, and, unlike the block3 case, there is no workaround for this kind of pointer component initialization.

As a side comment, I would have preferred for pointer assignments to always use the =\> notation rather than the = notation. That is, in an assignment statement I would have preferred the syntax

```auto
   x = t(n=>a)

```

rather than

```auto
   x = t(n=a)

```

when the pointer component name is used. Anyone have any idea why they did it the way they did?

---

<div class="post-metadata">

**Author:** ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)\
**Post date:** [January 23, 2023, 2:03am UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/16 "2023-01-23T02:03:41Z")

</div>

> [@RonShepard](#):
>
> Anyone have any idea why they did it the way they did?

You’re referring to the use of = in the structure constructor, as otherwise pointer assignment is always =\>. Here the = is not assignment but rather component identification. It’s a fine point, I’ll admit.

---

<div class="post-metadata">

**Author:** ![Knarfnarf](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Knarfnarf](https://fortran-lang.discourse.group/u/Knarfnarf)\
**Post date:** [February 1, 2023, 8:35pm UTC](https://fortran-lang.discourse.group/t/is-it-possible-to-initialize-a-linked-list/5064/17 "2023-02-01T20:35:48Z")

</div>

! Created Dec 2021  
! Version 0.1a  
! Updates: changes to some calls for ifort compatibility.  
! Updates: changes to try showing off constructor like functions.  
Program testing  
implicit none

! Declare types  
type :: t\_beanpole  
integer :: i\_value  
type(t\_beanpole), pointer :: p\_next, p\_last  
end type t\_beanpole

! Declare variables  
integer :: i\_list(3)  
type(t\_beanpole), pointer :: p\_root

! Start program  
print \*, “Testing program!”  
print \*, “Now testing linked list creation!”  
i\_list = (/11,11,11/)  
print \*, “Current array:”  
print \*, i\_list  
print \*, “New linked list:”  
call contructlist(i\_list, p\_root)  
call printlist(p\_root)

contains

! Subroutine to construct a linked list from an array.  
subroutine contructlist(i\_list, p\_root)  
implicit none

```
! Declare incoming variables and scope
! We are assuming only one dimension with the array...
integer, intent(in) :: i_list(:)
type(t_beanpole), pointer, intent(inout) :: p_root

! Declare local variables
integer :: i_loop, i_size
type(t_beanpole), pointer :: p_lefthand, p_righthand

! Start subroutine
i_size = size(i_list)
if (i_size .gt. 0) then ! if at least one.
  allocate(p_lefthand)
  p_lefthand%p_next => null()
  p_lefthand%p_last => null()
  p_lefthand%i_value = i_list(1)
  p_root => p_lefthand ! if more to link
  do i_loop = 2, size(i_list)
     allocate(p_righthand)
     p_righthand%p_next => null()
     p_righthand%p_last => p_lefthand
     p_lefthand%p_next => p_righthand
     p_lefthand => p_righthand
     p_lefthand%i_value = i_list(i_loop)
  end do
end if

```

end subroutine contructlist

! Subroutine to print a link list.  
subroutine printlist(p\_root)  
implicit none

```
! Declare incoming varibale and scope
type(t_beanpole), pointer, intent(in) :: p_root

! Declare local variables
type(t_beanpole), pointer :: p_lefthand

! Start subroutine
p_lefthand => p_root
do while(associated(p_lefthand)) ! Start at front
   print *, p_lefthand%i_value ! print
   p_lefthand => p_lefthand%p_next ! and keep going
end do

```

end subroutine printlist

end program testing

\*\*\*Might be a better bet?
